rewrites
rewritesを使用すると、受信リクエストのパスを別の宛先パスにマッピングできます。
rewritesはURLプロキシとして機能し、宛先パスをマスクするため、ユーザーがサイト上で位置を変更していないように見せかけます。これに対して、redirectsは新しいページにルートを変更し、URLの変更を表示します。
rewritesを使用するには、next.config.jsでrewritesキーを使用します:
module.exports = {
async rewrites() {
return [
{
source: '/about',
destination: '/',
},
]
},
}
rewritesはクライアントサイドのルーティングに適用され、上記の例では<Link href="/about">にrewriteが適用されます。
rewritesは非同期関数で、sourceとdestinationプロパティを持つオブジェクトを含む配列または配列のオブジェクトを返すことが期待されます(以下参照):
source:String- 受信リクエストのパスパターンですdestination:String- ルートしたいパスですbasePath:falseまたはundefined- falseの場合、マッチング時にbasePathは含まれません。外部のrewritesにのみ使用できますlocale:falseまたはundefined- マッチング時にロケールを含めるべきでないかどうかhasはtype、key、valueプロパティを持つhasオブジェクトの配列ですmissingはtype、key、valueプロパティを持つmissingオブジェクトの配列です
rewrites関数が配列を返す場合、rewritesはファイルシステム(pagesと/publicファイル)をチェックした後、動的ルートの前に適用されます。rewrites関数が特定の形状を持つ配列のオブジェクトを返す場合、この動作は変更され、より細かく制御できます。Next.jsのv10.1以降:
module.exports = {
async rewrites() {
return {
beforeFiles: [
// これらのrewritesはheaders/redirectsの後、
// すべてのファイル(_next/publicファイルを含む)の前にチェックされ、
// ページファイルを上書きすることができます
{
source: '/some-page',
destination: '/somewhere-else',
has: [{ type: 'query', key: 'overrideMe' }],
},
],
afterFiles: [
// これらのrewritesはpages/publicファイルがチェックされた後、
// 動的ルートの前にチェックされます
{
source: '/non-existent',
destination: '/somewhere-else',
},
],
fallback: [
// これらのrewritesはpages/publicファイルと動的ルートが
// チェックされた後にチェックされます
{
source: '/:path*',
destination: `https://my-old-site.com/:path*`,
},
],
}
},
}
Good to know:
beforeFilesのrewritesは、sourceがマッチした直後にファイルシステム/動的ルートをチェックせず、すべてのbeforeFilesがチェックされるまで続行します。
Next.jsのルートがチェックされる順序は次のとおりです:
- headersがチェック/適用されます
- redirectsがチェック/適用されます
beforeFilesのrewritesがチェック/適用されます- publicディレクトリからの静的ファイル、
_next/staticファイル、および非動的ページがチェック/提供されます afterFilesのrewritesがチェック/適用されます。これらのrewritesのいずれかがマッチした場合、各マッチ後に動的ルート/静的ファイルをチェックしますfallbackのrewritesがチェック/適用されます。これらは404ページのレンダリング前、動的ルート/すべての静的アセットがチェックされた後に適用されます。getStaticPathsでfallback: true/'blocking'を使用する場合、next.config.jsで定義されたfallbackrewritesは実行されません。
Rewriteパラメータ
rewriteでパラメータを使用する場合、パラメータがdestinationで使用されていない場合、デフォルトでクエリに渡されます。
module.exports = {
async rewrites() {
return [
{
source: '/old-about/:path*',
destination: '/about', // :pathパラメータはここで使用されていないため、クエリに自動的に渡されます
},
]
},
}
パラメータがdestinationで使用されている場合、パラメータはクエリに自動的に渡されません。
module.exports = {
async rewrites() {
return [
{
source: '/docs/:path*',
destination: '/:path*', // :pathパラメータはここで使用されているため、クエリに自動的に渡されません
},
]
},
}
destinationで既に使用されている場合でも、クエリでパラメータを手動で渡すことができます。
module.exports = {
async rewrites() {
return [
{
source: '/:first/:second',
destination: '/:first?second=:second',
// :firstパラメータはdestinationで使用されているため、:secondパラメータは
// クエリに自動的に追加されませんが、上記のように手動で追加できます
},
]
},
}
Good to know: Automatic Static Optimizationまたはprerenderingからの静的ページのパラメータは、ハイドレーション後にクライアントで解析され、クエリで提供されます。
パスマッチング
パスマッチングが許可されています。たとえば、/blog/:slugは/blog/hello-world(ネストされたパスなし)にマッチします:
module.exports = {
async rewrites() {
return [
{
source: '/blog/:slug',
destination: '/news/:slug', // マッチしたパラメータはdestinationで使用できます
},
]
},
}
ワイルドカードパスマッチング
ワイルドカードパスをマッチさせるには、パラメータの後に*を使用します。たとえば、/blog/:slug*は/blog/a/b/c/d/hello-worldにマッチします:
module.exports = {
async rewrites() {
return [
{
source: '/blog/:slug*',
destination: '/news/:slug*', // マッチしたパラメータはdestinationで使用できます
},
]
},
}
正規表現パスマッチング
正規表現パスをマッチさせるには、パラメータの後に正規表現を括弧で囲みます。たとえば、/blog/:slug(\\d{1,})は/blog/123にマッチしますが、/blog/abcにはマッチしません:
module.exports = {
async rewrites() {
return [
{
source: '/old-blog/:post(\\d{1,})',
destination: '/blog/:post', // マッチしたパラメータはdestinationで使用できます
},
]
},
}
次の文字(, ), {, }, [, ], |, \, ^, ., :, *, +, -, ?, $は正規表現パスマッチングに使用されるため、sourceで非特殊値として使用する場合は、前に\\を追加してエスケープする必要があります:
module.exports = {
async rewrites() {
return [
{
// これは`/english(default)/something`がリクエストされた場合にマッチします
source: '/english\\(default\\)/:slug',
destination: '/en-us/:slug',
},
]
},
}
ヘッダー、Cookie、およびクエリのマッチング
ヘッダー、Cookie、またはクエリの値がhasフィールドと一致する場合、またはmissingフィールドと一致しない場合にのみrewriteをマッチさせることができます。sourceとすべてのhasアイテムが一致し、すべてのmissingアイテムが一致しない場合にrewriteが適用されます。
hasとmissingアイテムには次のフィールドがあります:
type:String-header、cookie、host、またはqueryのいずれかである必要がありますkey:String- 一致させるために選択されたタイプのキーですvalue:Stringまたはundefined- チェックする値です。undefinedの場合、任意の値が一致します。特定の部分をキャプチャするために正規表現のような文字列を使用できます。たとえば、値first-(?<paramName>.*)がfirst-secondに使用される場合、secondは:paramNameでdestinationで使用できます。
module.exports = {
async rewrites() {
return [
// ヘッダー`x-rewrite-me`が存在する場合、
// このrewriteが適用されます
{
source: '/:path*',
has: [
{
type: 'header',
key: 'x-rewrite-me',
},
],
destination: '/another-page',
},
// ヘッダー`x-rewrite-me`が存在しない場合、
// このrewriteが適用されます
{
source: '/:path*',
missing: [
{
type: 'header',
key: 'x-rewrite-me',
},
],
destination: '/another-page',
},
// source、query、cookieが一致する場合、
// このrewriteが適用されます
{
source: '/specific/:path*',
has: [
{
type: 'query',
key: 'page',
// page値はdestinationで利用できません。
// なぜなら、値が提供されており、名前付きキャプチャグループを使用していないためです。
// 例:(?<page>home)
value: 'home',
},
{
type: 'cookie',
key: 'authorized',
value: 'true',
},
],
destination: '/:path*/home',
},
// ヘッダー`x-authorized`が存在し、
// 一致する値を含む場合、このrewriteが適用されます
{
source: '/:path*',
has: [
{
type: 'header',
key: 'x-authorized',
value: '(?<authorized>yes|true)',
},
],
destination: '/home?authorized=:authorized',
},
// ホストが`example.com`の場合、
// このrewriteが適用されます
{
source: '/:path*',
has: [
{
type: 'host',
value: 'example.com',
},
],
destination: '/another-page',
},
]
},
}
外部URLへのrewrite
rewritesを使用すると、外部URLにrewriteできます。これはNext.jsを段階的に採用するのに特に便利です。以下は、メインアプリの/blogルートを外部サイトにリダイレクトするためのrewriteの例です。
module.exports = {
async rewrites() {
return [
{
source: '/blog',
destination: 'https://example.com/blog',
},
{
source: '/blog/:slug',
destination: 'https://example.com/blog/:slug', // マッチしたパラメータは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のすべてのルートをチェックした後、既存のWebサイトへのプロキシにフォールバックさせることもできます。
この方法では、より多くのページをNext.jsに移行する際にrewritesの設定を変更する必要がありません。
module.exports = {
async rewrites() {
return {
fallback: [
{
source: '/:path*',
destination: `https://custom-routes-proxying-endpoint.vercel.app/:path*`,
},
],
}
},
}
basePathサポートを使用したrewrites
rewritesでbasePathサポートを活用する場合、sourceとdestinationのそれぞれにbasePathが自動的にプレフィックスされます。ただし、rewriteにbasePath: falseを追加した場合は除きます:
module.exports = {
basePath: '/docs',
async rewrites() {
return [
{
source: '/with-basePath', // 自動的に/docs/with-basePathになります
destination: '/another', // 自動的に/docs/anotherになります
},
{
// basePath: falseが設定されているため、/without-basePathに/docsを追加しません
// 注:これは内部のrewritesには使用できません。例:`destination: '/another'`
source: '/without-basePath',
destination: 'https://example.com',
basePath: false,
},
]
},
}
バージョン履歴
| バージョン | 変更点 |
|---|---|
v13.3.0 | missingが追加されました |
v10.2.0 | hasが追加されました |
v9.5.0 | Headersが追加されました |