【Next.js和訳】API Reference/next.config.js/Redirects
この記事について
この記事は、next.config.js/Redirectsの記事を和訳したものです。
記事内で使用する画像は、公式ドキュメント内の画像を引用して使用させていただいております。
リダイレクト
バージョン履歴
バージョン | 変更点 |
---|---|
v10.2.0 |
has が追加されました |
v9.5.0 |
Redirects が追加されました |
リダイレクトは、入力されたリクエストパスを別の宛先パスにリダイレクトすることができます。
リダイレクトは、Node.js 環境でのみ利用可能で、クライアントサイドのルーティングには影響しません。
Redirects を使用するには、next.config.js
でredirects
キーを使用します。
module.exports = {
async redirects() {
return [
{
source: "/about",
destination: "/",
permanent: true,
},
]
},
}
redirects
は非同期関数で、source
、destination
、permanent
のプロパティを持つオブジェクトを含む配列が返されることを期待しています。
-
source
は、受信するリクエストのパスパターンです。 -
destination
は、ルーティングしたいパスです。 -
permanent
は、リダイレクトが永続的かどうかを表します。 -
basePath
:false
またはundefined
- false の場合、マッチングの際に basePath が含まれません、外部の書き換えにのみ使用できます。 -
locale
:false
またはundefined
- マッチング時にロケールを含めないかどうかを指定します。 -
has
は、type
、key
、value
のプロパティを持つ has オブジェクトの配列です。
リダイレクトは、ページや /public
ファイルを含むファイルシステムの前にチェックされます。
リダイレクトが適用されると、リクエストで指定されたクエリ値はすべてリダイレクト先に渡されます。例えば、次のようなリダイレクト設定を見てみましょう。
{
source: '/old-blog/:path*',
destination: '/blog/:path*',
permanent: false
}
/old-blog/post-1?hello=world
がリクエストされた場合、クライアントは/blog/post-1?hello=world
にリダイレクトされます。
パスマッチ
例えば、/old-blog/:slug
は /old-blog/hello-world
にマッチします(ネストしたパスはありません)。
module.exports = {
async redirects() {
return [
{
source: "/old-blog/:slug",
destination: "/news/:slug", // マッチしたパラメータは、destinationで使用できます。
permanent: true,
},
]
},
}
ワイルドカードパスのマッチング
ワイルドカードパスにマッチさせるには、パラメータの後に*
を使います。例えば、/blog/:slug*
は、/blog/a/b/c/d/hello-world
にマッチします。
module.exports = {
async redirects() {
return [
{
source: "/blog/:slug*",
destination: "/news/:slug*", // マッチしたパラメーターは、destinationで使用できます。
permanent: true,
},
]
},
}
正規表現パスのマッチング
例えば、/post/:slug(\d{1,})
は、/post/123
にマッチしますが、/post/abc
にはマッチしません。
module.exports = {
async redirects() {
return [
{
source: "/post/:slug(\\{1,})",
destination: "/news/:slug", // マッチしたパラメータは、destinationで使用できます。
permanent: false,
},
]
},
}
以下の文字 (
, )
, {
, }
, :
, *
, +
, ?
は、正規表現のパスマッチングに使用されるため、source
内で非特殊な値として使用する場合は、文字の前に\\
を付けてエスケープする必要があります。
module.exports = {
async redirects() {
return [
{
// リクエストされた `/english(default)/something` にマッチします。
source: "/english(default)/:slug",
destination: "/en-us/:slug",
permanent: false,
},
]
},
}
Header, Cookie, and Query Matching
Header, Cookie, Query の値が一致した場合にのみリダイレクトを適用するには、has
フィールドを使用します。リダイレクトが適用されるには、source
とすべての has
アイテムの両方が一致する必要があります。
has
アイテムには、次のようなフィールドがあります。
-
type
:String
-header
、cookie
、host
、query
のいずれかでなければなりません。 -
key
:String
- 選択されたタイプのうち、照合するキーです。 -
value
:String
またはundefinded
- チェックする値で、未定義の場合はどんな値でもマッチします。例えば、first-(?<paramName>.*)
がfirst-second
に使用された場合、second
は:paramName
を持つ宛先で使用可能になります。
module.exports = {
async redirects() {
return [
// もし、ヘッダ `x-redirect-me` が存在する場合。
// このリダイレクトが適用されます
{
source: '/:path((?!another-page$).*)',
has: [
{
type: 'header',
key: 'x-redirect-me',
},
],
permanent: false,
destination: '/another-page',
},
// ソース、クエリ、クッキーが一致した場合。
// このリダイレクトが適用されます
{
source: '/specific/:path*',
has: [
{
type: 'query',
key: 'page',
// 値が提供されていて、かつ値が提供されていないので、
// ページの値は宛先では利用できません。
// 宛先では、値が提供されていて、かつ
// 例:(?<page>home)
value: 'home',
},
{
type: 'cookie',
key: 'authorized',
value: 'true',
},
],
permanent: false,
destination: '/another/:path*',
},
// ヘッダー `x-authorized` が存在し、かつ
// 一致する値が含まれていれば、このリダイレクトが適用されます。
{
source: '/',
has: [
{
type: 'header',
key: 'x-authorized',
value: '(?<authorized>yes|true)',
},
],
permanent: false,
destination: '/home?authorized=:authorized',
},
// ホストが `example.com` の場合。
// このリダイレクトが適用されます
{
source: '/:path((?!another-page$).*)',,
has: [
{
type: 'host',
value: 'example.com',
},
],
destination: '/another-page',
},
]
},
}
basePath サポートによるリダイレクト
basePath
サポートを利用したリダイレクトでは、リダイレクトにbasePath
: false
を追加しない限り、source
とdestination
のそれぞれにbasePath
が自動的に付加されます。
module.exports = {
basePath: '/docs',
async redirects() {
return [
{
source: '/with-basePath', // 自動的に /docs/with-basePath になります。
destination: '/another', // 自動的に /docs/another になります。
permanent: false,
},
{
//basePath: falseが設定されているので/docsは追加されません。
source: '/without-basePath',
destination: '/another',
basePath: false。
permanent: false。
},
]
},
}
国際化対応のリダイレクト
i18n
サポートをリダイレクトで活用する場合、リダイレクトにlocale: false
を追加しない限り、設定されたlocale
を処理するために、それぞれのsource
とdestination
は自動的にプレフィックスされます。locale: false
を使用した場合、正しくマッチさせるためには、source
とdestination
の前にロケールを付ける必要があります。
module.exports = {
i18n: {
locales:['en', 'fr', 'de'],
defaultLocale: 'en',
},
async redirects() {
return [
{
source: '/with-locale', // すべてのロケールを自動的に処理します。
destination: '/another', // 自動的にロケールを渡す
permanent: false,
},
{
// locale: false が設定されているため、ロケールを自動的に処理しない
rource: '/nl/with-locale-manual',
destination: '/nl/another',
locale:false
permanent: false。
},
{
// 「en」がデフォルトロケールであるため、「/」にマッチします。
source: '/en',
destination: '/en/another',
locale: false,
permanent: false,
},
{
// これは/(en|fr|de)/(.*)に変換されるので、トップレベルにはマッチしません。
// `/` や `/fr` のルートには /:path* のようにマッチしません。
source: '/(.*)',
destination: '/another',
permanent: false,
},
]
},
}
まれに、古い HTTP クライアントが適切にリダイレクトするために、カスタムのステータスコードを割り当てる必要がある場合があります。このような場合には、permanent
プロパティの代わりに statusCode
プロパティを使用できますが、両方を使用することはできません。注:IE11 との互換性を確保するため、308 のステータスコードにはRefresh
ヘッダーが自動的に追加されます。
その他のリダイレクト
-
API ルートの内部では、
res.redirect()
を使用できます。 -
getStaticProps
やgetServerSideProps
の内部では、リクエスト時に特定のページをリダイレクトすることができます。
Discussion