リダイレクト

パスのリダイレクトは、デプロイのルートに置く _redirects ファイルに、1行に1つずつ書きます。書式は、Netlify と Cloudflare Pages が読むものの一部です。

ファイル

/from   /to   [status]

項目はスペースかタブで区切ります。スペースやタブはいくつ続けても構いません。空白以外の最初の文字が # の行はコメントで、空行は読み飛ばされます。ルールと同じ行のうしろに書いたコメントは、余分な項目とみなされて受け付けられません。

ファイルはUTF-8で書きます。先頭のバイト順マークは無視され、改行は \n、\r\n、\r 単独のいずれも受け付けます。

ルールとして読まれるのは、デプロイのルートにある、名前がちょうど _redirects のファイルだけで、このファイルは配信されません。_Redirects や sub/_redirects は、ふつうのファイルとして配信されます。

ファイルの上限は64KB、ルールは1,000件、1行は2,048バイトまでです。

ルール

拡張子のない完全一致の移動元は、末尾にスラッシュの付いた形にも一致し、そのスラッシュを移動先にも付けます。ルール /about /elsewhere では、/about/ は /elsewhere/ にリダイレクトされます。移動先に拡張子、クエリ、フラグメントのいずれかがあれば、移動先は書いたとおりに使われるので、ルール /about /page.html では /about も /about/ も /page.html に向かいます。

同じパスにファイルがあっても、ルールが優先されます。Netlify では ! でルールを強制しない限りファイルが優先されますが、ここでは ! に対応していません。1つのパスは、リダイレクトかファイルのどちらかにしてください。

クエリ文字列

リクエストのクエリ文字列は、移動先に引き継がれます。ルール /old /new では /old?ref=spring は /new?ref=spring に、ルール /blog/* /articles/:splat では /blog/2024/post?ref=spring は /articles/2024/post?ref=spring にリダイレクトされます。

移動先に独自のクエリがある場合、リクエストのクエリはそのうしろに & でつながります。ルール /old /new?lang=en では、/old?ref=spring は /new?lang=en&ref=spring に向かいます。移動先のフラグメントは最後に残ります。

受け付けられない書き方

行に誤りがあったとき

誤った行が1つでもあると、デプロイ全体が行番号付きのエラーで失敗します。ディレクトリをデプロイするときは、kamakiri deploy がアップロードの前にファイルを検査します。アーカイブは、アップロードのあとにサービスが検査します。どちらの場合も、公開中のサイトは変わりません。

次のファイルは、3行目で 200 を指定しています。

/old-page /new-page 301
/blog/* /posts/:splat 301
/api/* /backend/:splat 200
$ kamakiri deploy ./dist
line 3: invalid status 200, must be 301, 302, 303, 307, or 308
$ kamakiri deploy ./dist
3行目: ステータス200は無効です。301、302、303、307、308のいずれかを指定してください

その行を直すか消して、もう一度デプロイしてください。

他サービスとの互換性

301 と 302 のルールは、Kamakiri、Netlify、Cloudflare Pages のどれでも同じように動きます。Netlify が記載しているのはこの2つだけです。ステータスを省いたルールは、ここと Netlify では 301、Cloudflare Pages では 302 になるので、コードをそろえたいときはステータスを書いてください。

例

# Exact, permanent (301 default)
/old/page/      /new/page/

# Temporary
/promo          /campaign/spring   302

# Wildcard: the suffix is carried to the target
/blog/*         /articles/:splat

# Versioned API, keep-method redirect
/api/v1/*       /api/v2/:splat      307