rewrites
リライトは、受信したリクエストパスを別の送信先パスにマッピングすることを可能にします。
リライトは URL プロキシとして機能し、送信先パスを隠すため、ユーザーはサイト上の場所を変更していないように見えます。対照的に、リダイレクトは新しいページにリダイレクトし、URL の変更を表示します。
リライトを使用するには、next.config.js
で rewrites
キーを使用できます。
module.exports = {
async rewrites() {
return [
{
source: '/about',
destination: '/',
},
]
},
}
リライトはクライアントサイドルーティングに適用されます。上記の例では、<Link href="/about">
にリライトが適用されます。
rewrites
は、source
と destination
プロパティを持つオブジェクトの配列、または配列のオブジェクト(下記参照)を返すことを期待する非同期関数です。
source
:String
- 受信リクエストパスのパターンです。destination
:String
- ルーティングしたいパスです。basePath
:false
またはundefined
-false
の場合、マッチング時に basePath は含まれません。これは外部リライトのみに使用できます。locale
:false
またはundefined
- マッチング時にロケールを含めるべきではないかどうか。has
は、type
、key
、value
プロパティを持つhas オブジェクトの配列です。missing
は、type
、key
、value
プロパティを持つmissing オブジェクトの配列です。
rewrites
関数が配列を返す場合、リライトはファイルシステム(ページと /public
ファイル)のチェック後、動的ルートの前に適用されます。rewrites
関数が特定の形状の配列のオブジェクトを返す場合、Next.js の v10.1
から、この動作を変更し、より細かく制御できます。
module.exports = {
async rewrites() {
return {
beforeFiles: [
// These rewrites are checked after headers/redirects
// and before all files including _next/public files which
// allows overriding page files
{
source: '/some-page',
destination: '/somewhere-else',
has: [{ type: 'query', key: 'overrideMe' }],
},
],
afterFiles: [
// These rewrites are checked after pages/public files
// are checked but before dynamic routes
{
source: '/non-existent',
destination: '/somewhere-else',
},
],
fallback: [
// These rewrites are checked after both pages/public files
// and dynamic routes are checked
{
source: '/:path*',
destination: `https://my-old-site.com/:path*`,
},
],
}
},
}
注意:
beforeFiles
のリライトは、ソースがマッチした後すぐにファイルシステム/動的ルートをチェックせず、すべてのbeforeFiles
がチェックされるまで続行します。
Next.js のルートがチェックされる順序は次のとおりです。
- ヘッダーがチェック/適用されます。
- リダイレクトがチェック/適用されます。
beforeFiles
リライトがチェック/適用されます。- public ディレクトリからの静的ファイル、
_next/static
ファイル、および非動的ページがチェック/提供されます。 afterFiles
リライトがチェック/適用されます。これらのリライトのいずれかがマッチした場合、各マッチ後に動的ルート/静的ファイルをチェックします。fallback
リライトがチェック/適用されます。これらは 404 ページのレンダリング前、および動的ルート/すべての静的アセットがチェックされた後に適用されます。getStaticPaths
で fallback: true/'blocking' を使用する場合、next.config.js
で定義された fallbackrewrites
は**実行されません**。
リライトパラメータ
リライトでパラメータを使用する場合、destination
でパラメータが使用されない場合、デフォルトでパラメータはクエリに渡されます。
module.exports = {
async rewrites() {
return [
{
source: '/old-about/:path*',
destination: '/about', // The :path parameter isn't used here so will be automatically passed in the query
},
]
},
}
パラメータがデスティネーションで使用されている場合、どのパラメータも自動的にクエリに渡されません。
module.exports = {
async rewrites() {
return [
{
source: '/docs/:path*',
destination: '/:path*', // The :path parameter is used here so will not be automatically passed in the query
},
]
},
}
パラメータが既にデスティネーションで使用されている場合でも、destination
でクエリを指定することで、手動でクエリにパラメータを渡すことができます。
module.exports = {
async rewrites() {
return [
{
source: '/:first/:second',
destination: '/:first?second=:second',
// Since the :first parameter is used in the destination the :second parameter
// will not automatically be added in the query although we can manually add it
// as shown above
},
]
},
}
注意: 自動静的最適化またはプリレンダリングからの静的ページのリライトからのパラメータは、ハイドレーション後にクライアントで解析され、クエリとして提供されます。
パスのマッチング
パスのマッチングは許可されており、例えば /blog/:slug
は /blog/hello-world
にマッチします(ネストされたパスは除く)。
module.exports = {
async rewrites() {
return [
{
source: '/blog/:slug',
destination: '/news/:slug', // Matched parameters can be used in the destination
},
]
},
}
ワイルドカードパスのマッチング
ワイルドカードパスにマッチさせるには、パラメータの後に *
を使用します。例えば、/blog/:slug*
は /blog/a/b/c/d/hello-world
にマッチします。
module.exports = {
async rewrites() {
return [
{
source: '/blog/:slug*',
destination: '/news/:slug*', // Matched parameters can be used in the destination
},
]
},
}
正規表現パスのマッチング
正規表現パスにマッチさせるには、パラメータの後に正規表現を括弧で囲みます。例えば、/blog/:slug(\\d{1,})
は /blog/123
にはマッチしますが、/blog/abc
にはマッチしません。
module.exports = {
async rewrites() {
return [
{
source: '/old-blog/:post(\\d{1,})',
destination: '/blog/:post', // Matched parameters can be used in the destination
},
]
},
}
(
、)
、{
、}
、[
、]
、|
、\
、^
、.
、:
、*
、+
、-
、?
、$
の文字は正規表現パスのマッチングに使用されるため、source
で特殊でない値として使用する場合は、それらの前に \\
を追加してエスケープする必要があります。
module.exports = {
async rewrites() {
return [
{
// this will match `/english(default)/something` being requested
source: '/english\\(default\\)/:slug',
destination: '/en-us/:slug',
},
]
},
}
ヘッダー、クッキー、およびクエリのマッチング
ヘッダー、クッキー、またはクエリの値も一致する場合、または missing
フィールドと一致しない場合にのみリライトを一致させるには、has
フィールドまたは missing
フィールドを使用できます。リライトが適用されるためには、source
とすべての has
アイテムが一致し、すべての missing
アイテムが一致しない必要があります。
has
および missing
アイテムには、以下のフィールドを含めることができます。
type
:String
-header
、cookie
、host
、またはquery
のいずれかでなければなりません。key
:String
- 照合する選択されたタイプのキーです。value
:String
またはundefined
- チェックする値で、undefined
の場合は任意の値が一致します。値の特定の部分をキャプチャするために正規表現のような文字列を使用できます。例えば、first-(?<paramName>.*)
という値がfirst-second
に使用された場合、second
は:paramName
でデスティネーションで使用可能になります。
module.exports = {
async rewrites() {
return [
// if the header `x-rewrite-me` is present,
// this rewrite will be applied
{
source: '/:path*',
has: [
{
type: 'header',
key: 'x-rewrite-me',
},
],
destination: '/another-page',
},
// if the header `x-rewrite-me` is not present,
// this rewrite will be applied
{
source: '/:path*',
missing: [
{
type: 'header',
key: 'x-rewrite-me',
},
],
destination: '/another-page',
},
// if the source, query, and cookie are matched,
// this rewrite 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',
},
],
destination: '/:path*/home',
},
// if the header `x-authorized` is present and
// contains a matching value, this rewrite will be applied
{
source: '/:path*',
has: [
{
type: 'header',
key: 'x-authorized',
value: '(?<authorized>yes|true)',
},
],
destination: '/home?authorized=:authorized',
},
// if the host is `example.com`,
// this rewrite will be applied
{
source: '/:path*',
has: [
{
type: 'host',
value: 'example.com',
},
],
destination: '/another-page',
},
]
},
}
外部URLへのリライト
リライトにより、外部 URL へのリライトが可能になります。これは、Next.js を段階的に導入する際に特に役立ちます。以下は、メインアプリの /blog
ルートを外部サイトにリダイレクトするリライトの例です。
module.exports = {
async rewrites() {
return [
{
source: '/blog',
destination: 'https://example.com/blog',
},
{
source: '/blog/:slug',
destination: 'https://example.com/blog/:slug', // Matched parameters can be used in the destination
},
]
},
}
trailingSlash: true
を使用している場合、source
パラメータにも末尾のスラッシュを挿入する必要があります。送信先サーバーも末尾のスラッシュを期待している場合は、destination
パラメータにも含める必要があります。
module.exports = {
trailingSlash: true,
async rewrites() {
return [
{
source: '/blog/',
destination: 'https://example.com/blog/',
},
{
source: '/blog/:path*/',
destination: 'https://example.com/blog/:path*/',
},
]
},
}
Next.js の段階的な導入
すべての Next.js ルートをチェックした後、既存のウェブサイトへのプロキシにフォールバックすることもできます。
これにより、より多くのページを Next.js に移行する際に、リライト設定を変更する必要がなくなります。
module.exports = {
async rewrites() {
return {
fallback: [
{
source: '/:path*',
destination: `https://custom-routes-proxying-endpoint.vercel.app/:path*`,
},
],
}
},
}
basePath サポート付きリライト
basePath
サポートをリライトと組み合わせて利用する場合、リライトに basePath: false
を追加しない限り、各 source
と destination
には自動的に basePath
がプレフィックスとして追加されます。
module.exports = {
basePath: '/docs',
async rewrites() {
return [
{
source: '/with-basePath', // automatically becomes /docs/with-basePath
destination: '/another', // automatically becomes /docs/another
},
{
// does not add /docs to /without-basePath since basePath: false is set
// Note: this can not be used for internal rewrites e.g. `destination: '/another'`
source: '/without-basePath',
destination: 'https://example.com',
basePath: false,
},
]
},
}
i18n サポート付きリライト
i18n
サポートをリライトと組み合わせて利用する場合、リライトに locale: false
を追加しない限り、各 source
と destination
は設定された locales
を処理するために自動的にプレフィックスが追加されます。locale: false
が使用されている場合、正しく一致させるためには source
と destination
にロケールをプレフィックスとして追加する必要があります。
module.exports = {
i18n: {
locales: ['en', 'fr', 'de'],
defaultLocale: 'en',
},
async rewrites() {
return [
{
source: '/with-locale', // automatically handles all locales
destination: '/another', // automatically passes the locale on
},
{
// does not handle locales automatically since locale: false is set
source: '/nl/with-locale-manual',
destination: '/nl/another',
locale: false,
},
{
// this matches '/' since `en` is the defaultLocale
source: '/en',
destination: '/en/another',
locale: false,
},
{
// it's possible to match all locales even when locale: false is set
source: '/:locale/api-alias/:path*',
destination: '/api/:path*',
locale: false,
},
{
// this gets converted to /(en|fr|de)/(.*) so will not match the top-level
// `/` or `/fr` routes like /:path* would
source: '/(.*)',
destination: '/another',
},
]
},
}
バージョン履歴
バージョン | 変更点 |
---|---|
v13.3.0 | missing が追加されました。 |
v10.2.0 | has が追加されました。 |
v9.5.0 | ヘッダーが追加されました。 |
役に立ちましたか?