【Next.js和訳】API Reference/next.config.js/Rewrites
この記事について
この記事は、next.config.js/Rewritesの記事を和訳したものです。
記事内で使用する画像は、公式ドキュメント内の画像を引用して使用させていただいております。
リライト
例
バージョン履歴
バージョンの変更点
v10.2.0
has
を追加しました。
v9.5.0
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 オブジェクトの配列です。
書き換えは、デフォルトでは、ファイルシステム(ページおよび/public
ファイル)をチェックした後、ダイナミックルートの前に適用されます。この動作は、Next.js のv10.1
以降、rewrites
関数から配列ではなくオブジェクトを返すことで変更できます。
module.exports = {
async rewrites() {
return {
beforeFiles: [
// これらの書き換えは、ヘッダ/リダイレクトの後にチェックされます。
// そして、_next/public ファイルを含むすべてのファイルの前にチェックされます。
// ページファイルを上書きすることができます
{
source: '/some-page',
destination: '/somewher-else',
has:[{ type: 'query', key: 'overrideMe' }],
},
],
afterFiles: [
// これらの書き換えは、ページ/パブリックファイルの後にチェックされます。
// がチェックされますが、ダイナミックルートの前に
{
source: '/non-existent',
destination: 'somewher-else',
},
],
fallback [
// これらの書き換えは、ページ/パブリックファイルの両方がチェックされた後にチェックされます。
// とダイナミックルートがチェックされます
{
source: '/:path*',
destination: `https://my-old-site.com/:path*`,
},
],
}
},
}
Next.js のルートがチェックされる順番は次のとおりです。
- ヘッダーがチェック/適用される
- リダイレクトがチェック/適用される
-
beforeFiles
の書き換えがチェック/適用される -
public ディレクトリの静的ファイル、
_next/static
ファイル、非動的なページのチェック/提供される -
afterFiles
の書き換えがチェックされ、適用されます。これらの書き換えにマッチした場合、各マッチの後にダイナミックルート/静的ファイルがチェックされます。 -
fallback
の書き換えがチェック/適用されます。これらの書き換えは、404 ページをレンダリングする前、およびダイナミックルート/すべてのスタティックアセットがチェックされた後に適用されます。
書き換えパラメータ
再書き込みでパラメータを使用する場合、パラメータがdestination
で使用されていない場合、パラメータはデフォルトでクエリに渡されます。
module.exports = {
async rewrites() {
return [
{
source: "/old-about/:path*",
destination: "/about", // :pathパラメータはここでは使用しないので、自動的にクエリに渡されます。
},
]
},
}
デスティネーションでパラメータが使用されている場合は、どのパラメータも自動的にクエリに渡されません。
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 パラメーターはデスティネーションで使用されているので、 :second パラメーターは // クエリには自動的に追加されません。
// 自動的には追加されませんが、手動で追加することは可能です。
// 上記のように
},
]
},
}
パスマッチ
パスマッチは許可されています。例えば、/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",
},
]
},
}
ヘッダ、クッキー、クエリのマッチング
ヘッダー、クッキー、クエリの値が一致した場合にのみリライトを適用するには、has
フィールドを使用できます。書き換えが適用されるには、source
とすべての has
アイテムの両方が一致する必要があります。
has
アイテムには、以下のフィールドがあります。
-
type
:String
-header
、cookie
、host
、query
のいずれかでなければなりません。 -
key
:String
- 選択されたタイプのうち、照合するキーです。 -
value
:String
またはundefinded
- チェックする値で、未定義の場合はどんな値でもマッチします。例えば、first-(?<paramName>.*)
がfirst-second
に使用された場合、second
は:paramName
を持つ宛先で使用可能になります。
module.exports = {
async rewrites() {
return [
// もし、ヘッダ `x-rewrite-me` が存在する場合。
// このリライトが適用されます
{
source: "/:path*",
has: [
{
type: "header",
key: "x-rewrite-me",
},
],
destination: "/another-page",
},
// ソース、クエリ、クッキーが一致した場合。
// このリライトが適用されます
{
source: "/specific/:path*",
has: [
{
type: "query",
key: "page",
// 値が提供されていて、かつ値が提供されていないので、 // ページの値は宛先では利用できません。
// 宛先では、値が提供されていて、かつ
// 例:(?<page>home)
value: "home",
},
{
type: "cookie",
key: "authorized",
value: "true",
},
],
destination: "/:path*/home",
},
// ヘッダ `x-authorized` が存在し、かつ
// 一致する値が含まれていれば、このような書き換えが行われます。
{
source: "/:path*",
has: [
{
type: "header",
key: "x-authorized",
value: "(?<authorized>yes|true)",
},
],
destination: "/home?authorized=:authorized",
},
// ホストが `example.com` の場合。
// このリライトが適用されます
{
source: "/:path*",
has: [
{
type: "host",
value: "example.com",
},
],
destination: "/another-page",
},
]
},
}
外部 URL への書き換え
Rewrites では、外部の URL に書き換えることができます。これは、Next.js を段階的に導入する際に特に有効です。
module.exports = {
async rewrites() {
を返します。
{
source: '/blog/:slug',
destination: 'https://example.com/blog/:slug', // マッチしたパラメータは、デスティネーションで使用できます。
},
]
},
}
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", // 自動的に /docs/with-basePath になります。
destination: "/another", // 自動的に /docs/another になります。
},
{
// basePath: falseが設定されているので、/docsは/without-basePathに追加されません。
// 注意:これは内部の書き換えには使えません 例:`destination: '/another'`)
source: "/without-basePath",
destination: "https://example.com",
basePath: false,
},
]
},
}
国際化対応の書き換え
i18n
サポートを書き換えで利用する場合、書き換えに locale: false
を追加しない限り、設定されたlocale
を処理するために各source
とdestination
は自動的にプレフィックスされます。locale: false
を使用した場合、正しくマッチさせるためには、source
とdestination
の前にロケールを付ける必要があります。
module.exports = {
i18n: {
locales: ["en", "fr", "de"],
defaultLocale: "en",
},
async rewrites() {
return [
{
source: "/with-locale", // すべてのロケールを自動的に処理します。
destination: "/another", // 自動的にロケールを渡す
},
{
// locale: false が設定されているため、ロケールを自動的に処理しない
source: "/nl/with-locale-manual",
destination: "/nl/another",
locale: false,
},
{
// 「en」がデフォルトロケールなので、「/」にマッチします。
source: "/en",
destination: "/en/another",
locale: false,
},
{
// これは、/(en|fr|de)/(.*)に変換されるので、トップレベルにはマッチしません。
// `/` や `/fr` のルートには /:path* のようにマッチしません。
source: "/(.*)",
destination: "/another",
},
]
},
}
Discussion