rewrites
Rewrites は、着信する request path を異なる destination path に map することを可能にします。
Rewrites は URL プロキシとして機能し、destination path を隠し、ユーザーがサイト上の場所を変えていないように見せます。対照的に、redirectsは新しいページに Redirect し、URL の変化を表示します。
next.config.js
のrewrites
キーを使用して、 rewrites を使用することができます:
module.exports = {
async rewrites() {
return [
{
source: '/about',
destination: '/',
},
]
},
}
Rewrites は Client 側のルーティングに適用され、<Link href="/about">
は上の例のように rewrite が適用されます。"
rewrites
は、source
とdestination
プロパティを持つオブジェクトを保持する配列、または配列の object (以下参照)を返すことを期待する async 関数です。
source
:String
- これは着信の request path パターンです。destination
:String
は、あなたが route したい path です。basePath
:false
またはundefined
- false の場合、basePath はマッチング時に含まれません。外部の書き換えにのみ使用できます。locale
:false
またはundefined
- ロケールをマッチング時に含めないかどうか。has
はtype
、key
、value
のプロパティを持つhas objectsの配列です。missing
はtype
、key
、value
のプロパティを持つmissing objectsの配列です。
rewrites
関数が配列を返すと、ファイルシステム(ページと/public
ファイル)をチェックした後、そして dynamic routes の前に rewrites が適用されます。rewrites
関数が特定の形状の配列の object を返すと、この動作は変更され、v10.1
の Next.js からより細かく制御することが可能になります。
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*`,
},
],
}
},
}
Good to know:
beforeFiles
の rewrites は、 source と一致した直後にファイルシステム/動的な routes をチェックしません、すべてのbeforeFiles
がチェックされるまで続きます。
Next.js routes の順番は次の通りです:
- headersは確認/適用されます
- redirectsが確認/適用されています
beforeFiles
rewrites がチェック/適用される- public ディレクトリからの静的ファイル、
_next/static
ファイル、および非動的ページが確認/提供されます。 afterFiles
の rewrites がチェック/適用された後、これらの rewrites のいずれかが一致する場合、それぞれの一致後に dynamic ルート/静的ファイルをチェックします。fallback
の rewrites はチェック/適用され、これらは 404 ページの rendering 前と dynamic な routes/すべての静的アセットがチェックされた後に適用されます。もしgetStaticPaths
で fallback: true/'blocking' を使用すると、あなたのnext.config.js
で定義された fallback のrewrites
が 実行されません。
Rewrite parameters
パラメータを rewrite で使うとき、どのパラメータもdestination
で使われていない場合、パラメータは query で default で渡されます。
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
},
]
},
}
パラメータが destination で使用されると、どのパラメータも自動的に 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 で使用されている場合でも、destination
に query を指定することで、query のパラメータを手動で渡すことができます。
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
},
]
},
}
Good to know: Automatic Static Optimizationまたはprerenderingからの静的ページは、hydration 後に client で解析され、query で提供されます。
Path Matching
Path の一致が許可されています。例えば、/blog/:slug
は/blog/hello-world
と一致します(ネストされたパスはありません):
module.exports = {
async rewrites() {
return [
{
source: '/blog/:slug',
destination: '/news/:slug', // Matched parameters can be used in the destination
},
]
},
}
Wildcard Path Matching
ワイルドカードパスに一致させたい場合、パラメーターの後に*
を使用できます。例えば、/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
},
]
},
}
Regex Path Matching
正規表現パスに一致させたい場合、パラメーターの後に括弧で正規表現を囲むことができます。例えば、/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
},
]
},
}
次の文字(
、)
、{
、}
、[
、]
、|
、\
、^
、.
、:
、*
、+
、-
、$
は regex path のマッチングに使用されるため、source
内で特殊でない値として使用される場合、それらの前に\\
を追加してエスケープする必要があります。
module.exports = {
async rewrites() {
return [
{
// this will match `/english(default)/something` being requested
source: '/english\\(default\\)/:slug',
destination: '/en-us/:slug',
},
]
},
}
Header, Cookie, and Query Matching
has
フィールドと一致するか、missing
フィールドと一致しないときにのみ、rewrite が header、cookie、または query の値と一致するようにすることができます。source
とすべてのhas
アイテムが一致しなければならず、すべてのmissing
アイテムが一致してはならない場合にのみ、rewrite が適用されます。
has
と missing
アイテムは以下のフィールドを持つことができます:
type
:String
-header
、cookie
、host
、またはquery
のいずれかでなければなりません。key
:String
- 選択されたタイプから一致させるためのキー。value
:String
または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',
},
]
},
}
Rewriting to an external URL
Examples
Rewrites を使用すると、外部の url に rewrite できます。これは特に、Next.js の段階的な導入に非常に便利です。以下は、メインの app の/blog
route を外部サイトに Redirect するための rewrite の例です。
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 server も末尾のスラッシュを期待している場合、それは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 routes をチェックした後、既存のウェブサイトへのプロキシ化にフォールバックすることもできます。
この方法を使用すれば、より多くのページを Next.js に移行する際に、 rewrites の設定を変更する必要がありません
module.exports = {
async rewrites() {
return {
fallback: [
{
source: '/:path*',
destination: `https://custom-routes-proxying-endpoint.vercel.app/:path*`,
},
],
}
},
}
Rewrites は basePath をサポートしています
basePath
サポートを使用する際に、 rewrite ごとに各source
とdestination
は、basePath: false
を rewrites に追加しない限り、自動的に 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,
},
]
},
}
Rewrites と i18n サポート
i18n
サポートを rewrites と共に利用する際、それぞれのsource
とdestination
は、あなたがlocale: false
を rewrite に追加しない限り、設定されたlocales
の処理を自動的にプレフィックスします。 locale: false
が使用される場合、それが正しく一致するためには、 source
と destination
を locale でプレフィックスする必要があります。
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',
},
]
},
}
Version History
Version | Changes |
---|---|
v13.3.0 | missing added. |
v10.2.0 | has added. |
v9.5.0 | Headers added. |