コンテンツにスキップ

redirects

リダイレクトにより、受信したリクエストパスを別の宛先パスにリダイレクトできます。

リダイレクトを使用するには、next.config.jsredirects キーを使用します。

next.config.js
module.exports = {
  async redirects() {
    return [
      {
        source: '/about',
        destination: '/',
        permanent: true,
      },
    ]
  },
}

redirects は非同期関数で、sourcedestinationpermanent プロパティを持つオブジェクトの配列を返す必要があります。

  • sourceは、着信リクエストパスのパターンです。
  • destination はルーティング先のパスです。
  • permanent true または false - true の場合は 308 ステータスコードが使用され、クライアント/検索エンジンにリダイレクトを永続的にキャッシュするように指示します。false の場合は 307 ステータスコードが使用され、一時的でありキャッシュされません。

Next.js はなぜ 307 と 308 を使用するのですか? 伝統的に 302 は一時的なリダイレクト、301 は永続的なリダイレクトに使用されていましたが、多くのブラウザは元のメソッドに関係なく、リダイレクトのメソッドを GET に変更していました。たとえば、ブラウザが POST /v1/users にリクエストを送信し、ロケーション /v2/users でステータスコード 302 を返した場合、後続のリクエストは期待される POST /v2/users ではなく GET /v2/users になる可能性があります。Next.js は、307 一時リダイレクトと 308 永続リダイレクトのステータスコードを使用して、使用されたリクエストメソッドを明示的に保持します。

  • basePath: false または undefined - false の場合、basePath はマッチング時に含まれません。外部リダイレクトにのみ使用できます。
  • locale: falseまたはundefined- matching時にlocaleを含めるべきかどうか。
  • hasは、typekeyvalueプロパティを持つhasオブジェクトの配列です。
  • missingは、typekeyvalueプロパティを持つmissingオブジェクトの配列です。

リダイレクトは、ファイルシステム(ページおよび /public ファイルを含む)よりも先にチェックされます。

Pages Router を使用する場合、リダイレクトは、Proxy が存在しパスに一致しない限り、クライアントサイドルーティング(Linkrouter.push)には適用されません。

リダイレクトが適用されると、リクエストで提供されたクエリ値はリダイレクト先に渡されます。たとえば、次のリダイレクト設定を参照してください。

{
  source: '/old-blog/:path*',
  destination: '/blog/:path*',
  permanent: false
}

知っておくと良いこと: パスパラメータの source および destination パスでは、コロン : の前にスラッシュ / を含めることを忘れないでください。そうしないと、パスはリテラル文字列として扱われ、無限リダイレクトを引き起こすリスクがあります。

/old-blog/post-1?hello=world がリクエストされると、クライアントは /blog/post-1?hello=world にリダイレクトされます。

パスマッチング

パスマッチングは許可されます。たとえば /old-blog/:slug/old-blog/hello-world にマッチしますが(ネストされたパスなし)、/old-blog/hello-world/nested にはマッチしません。

next.config.js
module.exports = {
  async redirects() {
    return [
      {
        source: '/old-blog/:slug',
        destination: '/news/:slug', // Matched parameters can be used in the destination
        permanent: true,
      },
    ]
  },
}

ワイルドカードパスマッチング

ワイルドカードパスに一致させるには、パラメータの後に*を使用します。例えば、/blog/:slug*/blog/a/b/c/d/hello-worldに一致します。

next.config.js
module.exports = {
  async redirects() {
    return [
      {
        source: '/blog/:slug*',
        destination: '/news/:slug*', // Matched parameters can be used in the destination
        permanent: true,
      },
    ]
  },
}

正規表現パスマッチング

正規表現パスにマッチするには、パラメータの後に正規表現を括弧で囲むことができます。たとえば /post/:slug(\\d{1,})/post/123 にマッチしますが、/post/abc にはマッチしません。

next.config.js
module.exports = {
  async redirects() {
    return [
      {
        source: '/post/:slug(\\d{1,})',
        destination: '/news/:slug', // Matched parameters can be used in the destination
        permanent: false,
      },
    ]
  },
}

特殊文字(){}:*+?は正規表現パスマッチングに使用されるため、sourceで特殊でない値として使用する場合は、前に\\を追加してエスケープする必要があります。

next.config.js
module.exports = {
  async redirects() {
    return [
      {
        // this will match `/english(default)/something` being requested
        source: '/english\\(default\\)/:slug',
        destination: '/en-us/:slug',
        permanent: false,
      },
    ]
  },
}

ヘッダー、Cookie、またはクエリ値が has フィールドに一致する場合、または missing フィールドに一致しない場合にのみリダイレクトをマッチさせるには、has フィールドまたは missing フィールドを使用できます。リダイレクトが適用されるには、source とすべての has アイテムが一致し、すべての missing アイテムが一致しない必要があります。

hasおよびmissing項目は、次のフィールドを持つことができます。

  • type: String- headercookiehost、またはqueryのいずれかである必要があります。
  • key: String- マッチング対象の選択されたタイプのキー。
  • value: Stringまたはundefined- チェックする値。undefinedの場合、値はすべて一致します。正規表現のような文字列を使用して、値の特定の部分をキャプチャできます。例えば、first-(?<paramName>.*)の値がfirst-secondに対して使用される場合、second:paramNameで宛先で使用できます。
next.config.js
module.exports = {
  async redirects() {
    return [
      // if the header `x-redirect-me` is present,
      // this redirect will be applied
      {
        source: '/:path((?!another-page$).*)',
        has: [
          {
            type: 'header',
            key: 'x-redirect-me',
          },
        ],
        permanent: false,
        destination: '/another-page',
      },
      // if the header `x-dont-redirect` is present,
      // this redirect will NOT be applied
      {
        source: '/:path((?!another-page$).*)',
        missing: [
          {
            type: 'header',
            key: 'x-do-not-redirect',
          },
        ],
        permanent: false,
        destination: '/another-page',
      },
      // if the source, query, and cookie are matched,
      // this redirect will be applied
      {
        source: '/specific/:path*',
        has: [
          {
            type: 'query',
            key: 'page',
            // the page value will not be available in the
            // destination since value is provided and doesn't
            // use a named capture group e.g. (?<page>home)
            value: 'home',
          },
          {
            type: 'cookie',
            key: 'authorized',
            value: 'true',
          },
        ],
        permanent: false,
        destination: '/another/:path*',
      },
      // if the header `x-authorized` is present and
      // contains a matching value, this redirect will be applied
      {
        source: '/',
        has: [
          {
            type: 'header',
            key: 'x-authorized',
            value: '(?<authorized>yes|true)',
          },
        ],
        permanent: false,
        destination: '/home?authorized=:authorized',
      },
      // if the host is `example.com`,
      // this redirect will be applied
      {
        source: '/:path((?!another-page$).*)',
        has: [
          {
            type: 'host',
            value: 'example.com',
          },
        ],
        permanent: false,
        destination: '/another-page',
      },
    ]
  },
}

basePath サポート付きリダイレクト

リダイレクトでbasePath サポートを活用する場合、リダイレクトに basePath: false を追加しない限り、各 source および destination には basePath が自動的にプレフィックスとして付与されます。

next.config.js
module.exports = {
  basePath: '/docs',
 
  async redirects() {
    return [
      {
        source: '/with-basePath', // automatically becomes /docs/with-basePath
        destination: '/another', // automatically becomes /docs/another
        permanent: false,
      },
      {
        // does not add /docs since basePath: false is set
        source: '/without-basePath',
        destination: 'https://example.com',
        basePath: false,
        permanent: false,
      },
    ]
  },
}

i18n サポート付きリダイレクト

App Router で国際化を伴うリダイレクトを実装する場合、next.config.js のリダイレクトにロケールを含めることができますが、ハードコードされたパスのみです。

動的またはリクエストごとのロケール処理については、ユーザーの好みの言語に基づいてリダイレクトできる動的ルートセグメントとプロキシを使用してください。

next.config.js
module.exports = {
  async redirects() {
    return [
      {
        // Manually handle locale prefixes for App Router
        source: '/en/old-path',
        destination: '/en/new-path',
        permanent: false,
      },
      {
        // Redirect for all locales using a parameter
        source: '/:locale/old-path',
        destination: '/:locale/new-path',
        permanent: false,
      },
      {
        // Redirect from one locale to another
        source: '/de/old-path',
        destination: '/en/new-path',
        permanent: false,
      },
      {
        // Catch-all redirect for multiple locales
        source: '/:locale(en|fr|de)/:path*',
        destination: '/:locale/new-section/:path*',
        permanent: false,
      },
    ]
  },
}

古い HTTP クライアントが正しくリダイレクトできるように、まれにカスタムステータスコードを割り当てる必要がある場合があります。この場合、permanent プロパティの代わりに statusCode プロパティを使用できますが、両方を同時に使用することはできません。IE11 との互換性を確保するために、308 ステータスコードには Refresh ヘッダーが自動的に追加されます。

その他のリダイレクト

バージョン履歴

バージョン変更履歴
v13.3.0missingが追加されました。
v10.2.0hasが追加されました。
v9.5.0redirects が追加されました。