【Next.js和訳】API Reference/next.config.js/Custom Headers
この記事について
この記事は、next.config.js/Custom Headersの記事を和訳したものです。
記事内で使用する画像は、公式ドキュメント内の画像を引用して使用させていただいております。
Headers
例
Version History
バージョン | 変更点 |
---|---|
v10.2.0 |
has を追加 |
v9.5.0 |
Headers を追加 |
Headers では、受信するリクエストパスにカスタム HTTP ヘッダーを設定することができます。
カスタム HTTP ヘッダーを設定するには、next.config.js
のheaders
キーを使用します。
module.exports = {
async headers() {
return [
{
source: "/about",
headers: [
{
key: "x-custom-header",
value: "my custom header value",
},
{
key: "x-another-custom-header",
value: "my other custom header value",
},
],
},
]
},
}
headers
は非同期関数で、source
とheaders
のプロパティを持つオブジェクトを含む配列が返されることを期待しています。
-
source
は、受信するリクエストのパスパターンです。 -
headers
は、key
とvalue
のプロパティを持つヘッダーオブジェクトの配列です。 -
basePath
:false
またはundefined
- false の場合、マッチングの際に basePath は含まれません、外部の書き換えにのみ使用できます。 -
locale
:false
またはundefined
- マッチング時にロケールを含めないかどうかです。 -
has
は、type
、key
、値のプロパティを持つhas
オブジェクトの配列です。
ヘッダーは、ページや /public
ファイルを含むファイルシステムよりも先にチェックされます。
ヘッダーのオーバーライド動作
2 つのヘッダが同じパスにマッチし、同じヘッダキーを設定している場合、最後に設定されたヘッダキーが最初に設定されたヘッダキーを上書きします。以下のヘッダーを使用すると、パスが/hello
の場合、最後に設定されたヘッダー値がworld
であるため、ヘッダー x-hello はworld
になります。
module.exports = {
async headers() {
return [
{
source: '/:path*',
headers: [
{
key: 'x-hello',
value: 'there',
},
],
},
{
source: '/hello',
headers: [
{
key: 'x-hello',
value: 'world',
},
],
},
],
},
}
パスマッチング
例えば、/blog/:slug
は/blog/hello-world
にマッチします(ネストしたパスはありません)。
module.exports = {
async headers() {
return [
{
source: '/blog/:slug',
headers: [
{
key: 'x-slug',
value: ':slug', // マッチしたパラメータはvalueに使用できます
},
{
key: 'x-slug-:slug', // 一致するパラメータは、keyに使用できます
value: 'my other custom header value',
},
],
},
],
},
}
ワイルドカード・パス・マッチング
ワイルドカードのパスにマッチさせるには、パラメータの後に*
を使います。例えば、/blog/:slug*
は、/blog/a/b/c/d/hello-world
にマッチします。
module.exports = {
async headers() {
return [
{
source: '/blog/:slug*',
headers: [
{
key: 'x-slug',
value: ':slug*', // 一致したパラメータは、valueの中で使用できます
},
{
key: 'x-slug-:slug*', // keyーにはマッチしたパラメーターが使用できます
value: 'my other custom header value',
},
],
},
],
},
}
Regex パスマッチング
例えば、/blog/:slug(\\d{1,})
は、/blog/123
にマッチしますが、/blog/abc
にはマッチしません。
module.exports = {
async headers() {
return [
{
source: '/blog/:post(\\d{1,})',
headers: [
{
key: 'x-post',
value: ':post',
},
],
},
],
},
}
以下の文字 (, )
、 {, }
、 :
、 *
、 +
、 ?
は、正規表現のパスマッチングに使用されるため、source
内で非特殊な値として使用する場合は、文字の前に\\
を付けてエスケープする必要があります。
module.exports = {
async headers() {
return [
{
// これは、リクエストされた `/english(default)/something` にマッチします
source: "/english\\(default\\)/:slug",
headers: [
{
key: "x-header",
value: "value",
},
],
},
]
},
}
ヘッダー、クッキー、およびクエリのマッチング
ヘッダー、クッキー、クエリのいずれかの値が一致した場合にのみヘッダーを適用するには、has
フィールドを使用できます。ヘッダーが適用されるには、source
とすべてのhas
アイテムの両方が一致する必要があります。
has
アイテムには、以下のフィールドがあります。
-
type
:String
-header
、cookie
、host
、query
のいずれかでなければなりません。 -
key
:String
- 選択されたタイプの中で、照合するキーです。 -
value
:String
またはundefined
- チェックする値、undefined の場合、いずれかの値が一致します。文字列のような正規表現を使用して、値の特定の部分をキャプチャできます。first-(?<paramName>.*)
という値がfirst-second
に使用されている場合、second
は宛先で:paramName
を使用して使用できます。
module.exports = {
async headers() {
return [
// ヘッダー `x-add-header` がある場合は、要求された `/english(default)/something` に
// x-another-header` というヘッダーが適用されます
{
source: "/:path*",
has: [
{
type: "header",
key: "x-add-header",
},
],
headers: [
{
key: "x-another-header",
value: "hello",
},
],
},
// ソース、クエリ、およびクッキーが一致した場合
// `x-authorized`ヘッダが適用されます
{
source: "/specific/:path*",
has: [
{
type: "query",
key: "page",
// ページの値は、ヘッダの key/values で利用できません。
// 値が提供されているので、ヘッダーのキー/値を
// (?<page>home)のように、名前付きのキャプチャグループを使用していません。
value: "home",
},
{
type: "cookie",
key: "authorized",
value: "true",
},
],
headers: [
{
key: "x-authorized",
value: ":authorized",
},
],
},
// もし、ヘッダ `x-authorized` が存在し、かつ
// 一致する値を含んでいれば、`x-another-header` が適用されます。
{
source: "/:path*",
has: [
{
type: "header",
key: "x-authorized",
value: "(?<authorized>yes|true)",
},
],
headers: [
{
key: "x-another-header",
value: ":authorized",
},
],
},
// if the host is `example.com`,
// this header will be applied
{
source: "/:path*",
has: [
{
type: "host",
value: "example.com",
},
],
headers: [
{
key: "x-another-header",
value: ":authorized",
},
],
},
]
},
}
国際化に対応したヘッダー
ヘッダーで国際化サポートを利用する場合、ヘッダーに locale: false
を追加しない限り、各source
は設定されたlocales
を扱うように自動的にプレフィックスされます。locale: false
を使用した場合、正しくマッチさせるためにはsource
の前にロケールを付ける必要があります。
module.exports = {
i18n: {
locales: ["en", "fr", "de"],
defaultLocale: "en",
},
async headers() {
return [
{
source: "/with-locale", // すべてのロケールを自動的に処理します
headers: [
{
key: "x-hello",
value: "world",
},
],
},
{
// locale: false が設定されているため、ロケールを自動的に処理しない
source: "/nl/with-locale-manual",
locale: false,
headers: [
{
key: "x-hello",
value: "world",
},
],
},
{
// `en` が defaultLocale なので、これは '/' にマッチします
source: "/en",
locale: false,
headers: [
{
key: "x-hello",
value: "world",
},
],
},
{
// ホストが `example.com` の場合。
// このヘッダが適用されます
source: "/(.*)",
headers: [
{
key: "x-hello",
value: "worlld",
},
],
},
]
},
}
キャッシュ-コントロール
next.config.js で設定された Cache-Control ヘッダは、運用時には上書きされ、静的資産が効果的にキャッシュされるようになります。静的生成されたページのキャッシュを再検証する必要がある場合は、ページのgetStaticProps
関数でrevalidate
を設定することで可能となります。
関連
詳細については、以下のセクションをお勧めします。
セキュリティヘッダー
HTTP レスポンスヘッダーを追加することで、Next.js アプリケーションのセキュリティを向上させることができます。
Discussion