Next.js を使っていると、next.config.ts に登場する rewrites という設定を目にすることがあります。
- 「URL を変えずに API にアクセスできるらしい」
- 「CORS 対策になる」
- 「Docker 構成でよく使われる」
こうした断片的な説明はよく見かけますが、次のような内容まで整理されている情報はあまり見かけません。
- 結局 rewrite とは何なのか
- どんな時に使うべきか
- どんな時に不要なのか
この記事では、Next.js の rewrite を 基礎 → 仕組み → 実務的なメリット → 設計上の注意点 → 削除という判断まで、順を追って解説します。
Next.js の rewrite の概要
rewrite は、URL を変えずに、サーバー側で別の URL にリクエストを転送する仕組みです。
- ブラウザのアドレスバーは変わらない
- HTTP ステータスコードも 301 / 302 ではない
- クライアントは「同じオリジン」にアクセスしている感覚のまま
リダイレクトとは違って、クライアントに見せずに裏側で交通整理をして、別の場所にアクセスするとも言い換えられます。
つまり、Next.js が リバースプロキシの役割を担います。
rewrite と redirect との違い
ここは混同されやすいポイントなので、先に整理します。
| 項目 | rewrite | redirect |
|---|---|---|
| URL 表示 | 変わらない | 変わる |
| 処理場所 | サーバー内部 | クライアント |
| 主な用途 | API プロキシ | URL 正規化・移転 |
| SEO | 影響なし | 301/302 の意味を持つ |
rewrite は 「内部転送」、redirect は「外部転送」と覚えると理解しやすいです。
rewrite の基本的な書き方
// next.config.ts
export default {
async rewrites() {
return [
{
source: '/api/:path*',
destination: 'http://localhost:8000/api/:path*',
},
];
},
};この設定により、クライアントから/api/users/にアクセスがあると、実際には以下にリクエストが投げられます。
http://localhost:8000/api/users/つまり、sourceはクライアントがアクセスするURLであり、destinationは「Next.jsサーバー」が内部的に転送する先になります。
/:path* は ワイルドカードで、後続のパスをそのまま渡します。
rewrite が動作する仕組み
rewrite のリクエストの流れは次のとおりです。
- ブラウザが Next.js サーバーにリクエスト
- Next.js が
rewrites設定をチェック - 条件に一致すれば、内部的に別 URL に転送
- レスポンスをクライアントに返却
クライアントは 「Next.js にアクセスした」という認識のままです。
また、rewrite が同一オリジン扱いになる理由については、 Next.js サーバーが代理で通信するため、次の二段構えになるからです。
- ブラウザ → Next.js
- Next.js → バックエンド
その結果、次のような利点が生まれます。
- CORS 設定が不要
- Cookie / 認証ヘッダを扱いやすい
rewrite を使うメリット
rewriteを使う場合、いくつかメリットがあります。
クライアント側の実装がシンプルになる
次のように、相対パスでAPIを呼べるのは大きなメリットです。
fetch('/api/agencies/');これにより、環境ごとのURL切り替えが不要になり、.envを意識しないでよくなります。
Docker 構成との相性が良い
Next.js とバックエンドが Docker 内で動いている場合、次のような内部ネットワーク名はブラウザから見られません。
http://backend:8000rewrite を使えば、ブラウザはNext.jsにだけアクセスをし、Next.jsが内部ネットワーク経由で接続するという構図が成り立ちます。
CORS を考えなくて済む
rewrite は 同一オリジン扱いになるので、次のようなCORSを考えなくて済みます。
- Django / FastAPI 側の CORS 設定
- 本番・開発の切り替え
応用:環境分岐を含む rewrite 設定
実務では、以下のような構成がよく見られます。
async rewrites() {
const isProduction =
process.env.NEXT_PUBLIC_APP_ENV === 'production';
const apiUrl = isProduction
? 'http://backend_kanteiman:8030'
: 'http://localhost:8000';
return [
{
source: '/api/:path*',
destination: `${apiUrl}/api/:path*`,
basePath: false,
},
{
source: '/__auth_api__/:path*',
destination: `${apiUrl}/auth/:path*`,
basePath: false,
},
];
}この設計でできることは、次のとおりです。
- クライアントは
/api/...や/__auth_api__/...にアクセス - Next.js が環境に応じてバックエンドを切り替え
- 本番では Docker 内部ネットワークを使用
設計としては筋が通っています。
「rewrite を使わないという」判断
rewrite はあくまで 選択肢の一つです。
以下のような構成では、rewrite は不要になります。
- API のベース URL を
getApiBaseUrl()で一元管理 - クライアントが直接 DRF / FastAPI に接続
- 認証 API も同じ方式で統一
実際に、次のようなことが起きがちです。
- 通常 API と Auth API で取得方法が違う
NEXT_PUBLIC_API_URL未設定時だけ rewrite を使う、などの非現実的な分岐- 設定を読まないと通信経路が分からない
つまり、「動くけど、理解しづらい構成」になりがちという問題点もあります。
そのため、次のような設計も健全といえます。
- rewrite を削除
- API 呼び出しをすべて
getApiBaseUrl()に統一 - Next.js はフロントエンドに集中
rewrite を使うべきかどうかの判断基準
rewrite が向いているケースは、例えば次のとおり。
- フロントとバックエンドが密結合
- CORS を極力避けたい
- Docker 内部ネットワークを隠したい
- BFF(Backend for Frontend)構成
逆に、次のような場合にはrewriteを使わないほうが良いです。
- API URL を明示的に管理している
- SSR / RSC でサーバー側 fetch が中心
- 設定の単純さを重視したい
- 通信経路を明確にしたい
まとめ
- rewrite は Next.js のプロキシ機能
- URL を変えずに内部転送できる強力な仕組み
- CORS 回避や Docker 構成で特に有効
- しかし 使わない判断も正解
- 実際に使われていない rewrite は、削除して統一した方が良い
rewrite は「入れること」よりも、
「なぜ入れるのか」「なぜ外すのか」を説明できることが重要です。
設計をシンプルにするために rewrite を削除する、
それもまた 正しい Next.js の使い方です。
コメント