Next.js 16でmiddleware.tsに代わったproxy.tsの実例集。認証リダイレクト、国別ルーティング、A/Bテスト用クッキー、言語判定、matcher、シミュレーターを用意しています。
Next.js 16では、Middlewareのファイル名はproxy.tsになり、proxyという名前の関数をエクスポートします。middleware.tsは非推奨となり、コードモッドで名前を変更できます。この関数はNextRequestを受け取り、リダイレクト、リライト、ヘッダーやクッキーの設定、レスポンスの返却を行えます。config.matcherで実行するパスを制限します。現在はデフォルトでNode.jsランタイムを使います。
Next.js 16での変更点
ネット上の回答の多くは、いまだにEdgeランタイムで動くmiddleware.tsを説明しています。ここで紹介する例は現在のファイル名を使い、そのまま動作し、応用しやすい短さに収めています。デプロイ前にシミュレーターを試せば、複数の処理を組み合わせたproxyのどの分岐が、特定のリクエストで実行されるかを確認できます。
非推奨になったのは名前です。バージョン16ではMiddlewareのファイル規約が非推奨となり、同じリクエストとレスポンスのAPIのままproxyに名前が変わりました。古いmiddleware.tsは移行することが想定されており、公式のコードモッドがファイル名とエクスポートする関数名の両方を変更します。
Next.jsチームによると、Middlewareという言葉がExpressのMiddlewareと混同され、使いすぎを招いていたためです。Proxyはアプリの手前にあるネットワークの境界を表す言葉で、ほかに適したAPIがない場合の最後の手段として使うよう推奨されています。
使えません。ProxyのデフォルトはNode.jsで、proxyファイルでランタイムのセグメントオプションを設定するとエラーになります。その代わり、Node.js専用のライブラリが使えるようになりました。これは、Edge専用だった以前のMiddlewareに対するよくある不満でした。
最初のフィルターとしてだけ使いましょう。Next.jsの認証ガイドでは、すばやくリダイレクトするためにproxyでセッションクッキーを読み、データアクセス層、Server Actions、Route Handlersでもう一度セッションを検証するよう推奨しています。matcherで除外されたServer Functionsは、proxyを完全に素通りします。
動きません。実行するサーバーがないため、ドキュメントのプラットフォーム表では静的エクスポートは非対応とされています。Node.jsサーバーとDockerは対応しており、ほかのホスティングはアダプター次第です。
config.matcherのパスの動き
楽観的なチェックです。セッションクッキーの有無だけを確認し、訪問者が向かっていた先を記憶します。
訪問者のURLは/pricingのままで、EU向けページが表示されます。ここで使っている国のヘッダーはVercelが付与するものです。ほかのホスティングでは独自のヘッダー名を使います。
訪問者は一度だけグループに割り当てられ、クッキーによってそのグループにとどまり、リライトによって同じURLでバリエーションが表示されます。
すでに対応ロケールで始まるパスはそのまま通過します。それ以外は、Accept-Languageで最初に一致した言語を使ってリダイレクトされます。
requestオプションの中でヘッダーを設定すると、ブラウザーに公開することなく、ルート側でheaders()を使って読み取れます。
認証の例:保護されたパスで、セッションクッキーがありません。
国の例:{country}はEUの一覧に含まれるため、同じURLでEU向けページが表示されます。
A/Bの例:訪問者はグループ{bucket}に属し、クッキーによってそのまま維持されます。
言語のmatcherで除外されているため、リクエストはそのまま続行されます。
言語の例:パスにすでに対応ロケールが含まれています。
言語の例:ヘッダー内で最初に対応している言語は{locale}です。
パス、セッションクッキー、国、ブラウザーの言語を設定すると、下の例がリクエストを通過させるか、リダイレクトするか、リライトするかを確認できます。
リクエストのパス
国のヘッダー(x-vercel-ip-country)
Accept-Languageヘッダー
A/Bのクッキーグループ
リクエストにセッションクッキーがある
無料で始める · クレジットカード不要