ミドルウェア
ミドルウェアを使用すると、リクエストが完了する前にコードを実行できます。その後、受信リクエストに基づいて、書き換え、リダイレクト、リクエストまたはレスポンスヘッダーの変更、または直接レスポンスを行うことで、レスポンスを変更できます。
ミドルウェアは、キャッシュされたコンテンツとルートがマッチングされる前に実行されます。詳細はパスのマッチングを参照してください。
ミドルウェアをアプリケーションに統合することで、パフォーマンス、セキュリティ、ユーザーエクスペリエンスに大きな改善をもたらすことができます。ミドルウェアが特に効果的な一般的なシナリオは次のとおりです:
- 認証と認可:特定のページやAPIルートにアクセスする前に、ユーザーの身元を確認し、セッションクッキーを確認します。
- サーバーサイドリダイレクト:ロケールやユーザーロールなどの特定の条件に基づいて、サーバーレベルでユーザーをリダイレクトします。
- パスの書き換え:リクエストのプロパティに基づいて、APIルートやページへのパスを動的に書き換えることで、A/Bテスト、機能のロールアウト、または従来のパスをサポートします。
- ボット検出:ボットトラフィックを検出およびブロックすることで、リソースを保護します。
- ログとアナリティクス:ページまたはAPIで処理される前に、リクエストデータをキャプチャして分析します。
- 機能フラグ:機能のシームレスなロールアウトやテストのために、動的に機能を有効または無効にします。
ミドルウェアが最適なアプローチではない状況を認識することも同様に重要です。注意すべきシナリオは次のとおりです:
- 複雑なデータフェッチと操作:ミドルウェアは直接のデータフェッチや操作のために設計されていません。これはルートハンドラまたはサーバーサイドユーティリティ内で行う必要があります。
- 重い計算タスク:ミドルウェアは軽量で迅速に応答する必要があり、そうでないとページ読み込みに遅延を引き起こす可能性があります。重い計算タスクや長時間実行されるプロセスは、専用のルートハンドラ内で行う必要があります。
- 広範なセッション管理:ミドルウェアは基本的なセッションタスクを管理できますが、広範なセッション管理は専用の認証サービスまたはルートハンドラ内で管理する必要があります。
- 直接データベース操作:ミドルウェア内で直接データベース操作を実行することはお勧めできません。データベースの相互作用は、ルートハンドラまたはサーバーサイドユーティリティ内で行う必要があります。
プロジェクトのルートに middleware.ts
(または .js
)ファイルを使用して、ミドルウェアを定義します。例えば、pages
または app
と同じレベル、または該当する場合は src
内に配置します。
注意: プロジェクトごとに1つの middleware.ts
ファイルのみがサポートされますが、ミドルウェアロジックをモジュール化して整理することはできます。ミドルウェア機能を別の .ts
または .js
ファイルに分割し、メインの middleware.ts
ファイルにインポートできます。これにより、ルート固有のミドルウェアを整理し、集中管理のために middleware.ts
に集約できます。単一のミドルウェアファイルを強制することで、設定が簡素化され、潜在的な競合が防止され、複数のミドルウェア層を回避することでパフォーマンスが最適化されます。
ミドルウェアはプロジェクト内のすべてのルートで呼び出されます。これを考慮すると、特定のルートを正確にターゲットまたは除外するためにマッチャーを使用することが重要です。実行順序は次のとおりです:
next.config.js
の headers
next.config.js
の redirects
- ミドルウェア(
rewrites
、redirects
など)
next.config.js
の beforeFiles
(rewrites
)
- ファイルシステムルート(
public/
、_next/static/
、pages/
、app/
など)
next.config.js
の afterFiles
(rewrites
)
- 動的ルート(
/blog/[slug]
)
next.config.js
の fallback
(rewrites
)
ミドルウェアが実行されるパスを定義する方法は2つあります:
- カスタムマッチャー設定
- 条件文
matcher
を使用すると、特定のパスでのみミドルウェアを実行するようにフィルタリングできます。
配列構文を使用して、単一のパスまたは複数のパスをマッチングできます:
matcher
設定は完全な正規表現を許可するため、否定先読みや文字マッチングがサポートされます。特定のパスを除くすべてのリクエストパスをマッチングする否定先読みの例を次に示します:
missing
または has
配列、またはその両方の組み合わせを使用して、特定のリクエストのミドルウェアを回避することもできます:
補足: matcher
の値は、ビルド時に静的に分析できるように、定数である必要があります。変数などの動的な値は無視されます。
設定されたマッチャーは:
/
で始める必要があります
- 名前付きパラメーターを含めることができます:
/about/:path
は /about/a
と /about/b
にマッチしますが、/about/a/c
にはマッチしません
- 名前付きパラメーターに修飾子を付けることができます(
:
で開始):/about/:path*
は *
が ゼロ以上 であるため /about/a/b/c
にマッチします。?
は ゼロまたは1 で、+
は 1以上 です
- 括弧で囲まれた正規表現を使用できます:
/about/(.*)
は /about/:path*
と同じです
詳細は path-to-regexp ドキュメントをお読みください。
補足: 下位互換性のため、Next.jsは常に /public
を /public/index
と見なします。したがって、/public/:path
のマッチャーはマッチします。
NextResponse
APIにより、以下のことが可能です:
- 受信リクエストを別のURLに
redirect
する
- 指定されたURLを表示することで応答を
rewrite
する
- API Routes、
getServerSideProps
、およびrewrite
の宛先のリクエストヘッダーを設定する
- 応答クッキーを設定する
- 応答ヘッダーを設定する
ミドルウェアから応答を生成するには、以下の方法があります:
- 応答を生成するルート(PageまたはRoute Handler)に
rewrite
する
- 直接
NextResponse
を返す。応答の生成を参照
クッキーは通常のヘッダーです。Request
では、Cookie
ヘッダーに保存され、Response
ではSet-Cookie
ヘッダーに保存されます。Next.jsはNextRequest
とNextResponse
のcookies
拡張を通じてこれらのクッキーにアクセスし、操作する便利な方法を提供します。
- 受信リクエストの場合、
cookies
にはget
、getAll
、set
、delete
のメソッドがあります。has
でクッキーの存在を確認したり、clear
ですべてのクッキーを削除したりできます。
- 送信応答の場合、
cookies
にはget
、getAll
、set
、delete
のメソッドがあります。
NextResponse
APIを使用してリクエストおよび応答ヘッダーを設定できます(リクエストヘッダーの設定はNext.js v13.0.0から利用可能)。
補足: バックエンドのウェブサーバー設定によっては、大きなヘッダーを設定すると431 Request Header Fields Too Largeエラーが発生する可能性があるため、避けてください。
ミドルウェアでCORSヘッダーを設定し、シンプルおよびプリフライトリクエストを含むクロスオリジンリクエストを許可できます。
補足: Route Handlersで個々のルートのCORSヘッダーを設定できます。
Middlewareから直接、Response
またはNextResponse
インスタンスを返すことでレスポンスできます。(これはNext.js v13.1.0から利用可能です)
NextFetchEvent
オブジェクトはネイティブのFetchEvent
オブジェクトを拡張し、waitUntil()
メソッドを含みます。
waitUntil()
メソッドはプロミスを引数として受け取り、プロミスが解決するまでMiddlewareの有効期間を延長します。これはバックグラウンドで作業を実行する際に有用です。
Next.jsのv13.1では、高度なユースケースを処理するために、skipMiddlewareUrlNormalize
とskipTrailingSlashRedirect
の2つの追加フラグが導入されました。
skipTrailingSlashRedirect
は、末尾のスラッシュを追加または削除するNext.jsのリダイレクトを無効にします。これにより、ミドルウェア内でいくつかのパスの末尾のスラッシュを維持し、他のパスは維持しないカスタム処理が可能になり、段階的な移行を容易にできます。
skipMiddlewareUrlNormalize
は、直接アクセスとクライアント遷移を同じように処理するために、Next.jsのURL正規化を無効にします。一部の高度なケースでは、このオプションにより元のURLを使用して完全な制御が可能になります。
現在、MiddlewareはEdge runtimeと互換性のあるAPIのみをサポートしています。Node.js専用のAPIはサポートされていません。
バージョン | 変更点 |
---|
v13.1.0 | 高度なMiddlewareフラグが追加 |
v13.0.0 | Middlewareがリクエストヘッダー、レスポンスヘッダーを変更し、レスポンスを送信できるようになった |
v12.2.0 | Middlewareが安定版となり、アップグレードガイドを参照してください |
v12.0.9 | Edge Runtimeで絶対URLを強制 (PR) |
v12.0.0 | Middleware(ベータ版)が追加 |