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の場合、matching時にbasePathは含まれません。外部リライトにのみ使用できます。locale:falseまたはundefined- matching時にlocaleを含めるべきかどうか。hasは、type、key、valueプロパティを持つhasオブジェクトの配列です。missingは、type、key、valueプロパティを持つmissingオブジェクトの配列です。
ヘッダーは、ファイルシステム(pagesや/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', // Matched parameters can be used in the value
},
{
key: 'x-slug-:slug', // Matched parameters can be used in the 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*', // Matched parameters can be used in the value
},
{
key: 'x-slug-:slug*', // Matched parameters can be used in the key
value: 'my other custom header value',
},
],
},
]
},
}正規表現パスマッチング
正規表現パスに一致させるには、パラメータの後に括弧で正規表現を囲みます。例えば、/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 [
{
// this will match `/english(default)/something` being requested
source: '/english\\(default\\)/:slug',
headers: [
{
key: 'x-header',
value: 'value',
},
],
},
]
},
}ヘッダー、Cookie、クエリのマッチング
ヘッダー、Cookie、またはクエリの値がhasフィールドに一致する場合、またはmissingフィールドに一致しない場合にのみヘッダーを適用するには、hasフィールドまたはmissingフィールドを使用できます。ヘッダーを適用するには、sourceとすべてのhas項目が一致し、すべてのmissing項目が一致しない必要があります。
hasおよびmissing項目は、次のフィールドを持つことができます。
type:String-header、cookie、host、またはqueryのいずれかである必要があります。key:String- マッチング対象の選択されたタイプのキー。value:Stringまたはundefined- チェックする値。undefinedの場合、値はすべて一致します。正規表現のような文字列を使用して、値の特定の部分をキャプチャできます。例えば、first-(?<paramName>.*)の値がfirst-secondに対して使用される場合、secondは:paramNameで宛先で使用できます。
module.exports = {
async headers() {
return [
// if the header `x-add-header` is present,
// the `x-another-header` header will be applied
{
source: '/:path*',
has: [
{
type: 'header',
key: 'x-add-header',
},
],
headers: [
{
key: 'x-another-header',
value: 'hello',
},
],
},
// if the header `x-no-header` is not present,
// the `x-another-header` header will be applied
{
source: '/:path*',
missing: [
{
type: 'header',
key: 'x-no-header',
},
],
headers: [
{
key: 'x-another-header',
value: 'hello',
},
],
},
// if the source, query, and cookie are matched,
// the `x-authorized` header will be applied
{
source: '/specific/:path*',
has: [
{
type: 'query',
key: 'page',
// the page value will not be available in the
// header key/values since value is provided and
// doesn't use a named capture group e.g. (?<page>home)
value: 'home',
},
{
type: 'cookie',
key: 'authorized',
value: 'true',
},
],
headers: [
{
key: 'x-authorized',
value: ':authorized',
},
],
},
// if the header `x-authorized` is present and
// contains a matching value, the `x-another-header` will be applied
{
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',
},
],
},
]
},
}basePathサポート付きヘッダー
basePathサポートをヘッダーで活用する場合、basePath: falseをヘッダーに追加しない限り、各sourceは自動的にbasePathでプレフィックスされます。
module.exports = {
basePath: '/docs',
async headers() {
return [
{
source: '/with-basePath', // becomes /docs/with-basePath
headers: [
{
key: 'x-hello',
value: 'world',
},
],
},
{
source: '/without-basePath', // is not modified since basePath: false is set
headers: [
{
key: 'x-hello',
value: 'world',
},
],
basePath: false,
},
]
},
}i18nサポート付きヘッダー
i18nサポートをヘッダーで活用する場合、locale: falseをヘッダーに追加しない限り、各sourceは構成されたlocalesを処理するために自動的にプレフィックスされます。locale: falseを使用する場合、正しくマッチングするためにsourceにロケールをプレフィックスする必要があります。
module.exports = {
i18n: {
locales: ['en', 'fr', 'de'],
defaultLocale: 'en',
},
async headers() {
return [
{
source: '/with-locale', // automatically handles all locales
headers: [
{
key: 'x-hello',
value: 'world',
},
],
},
{
// does not handle locales automatically since locale: false is set
source: '/nl/with-locale-manual',
locale: false,
headers: [
{
key: 'x-hello',
value: 'world',
},
],
},
{
// this matches '/' since `en` is the defaultLocale
source: '/en',
locale: false,
headers: [
{
key: 'x-hello',
value: 'world',
},
],
},
{
// this gets converted to /(en|fr|de)/(.*) so will not match the top-level
// `/` or `/fr` routes like /:path* would
source: '/(.*)',
headers: [
{
key: 'x-hello',
value: 'world',
},
],
},
]
},
}Cache-Control
Next.jsは、真に不変なアセットに対してCache-Controlヘッダーをpublic, max-age=31536000, immutableに設定します。これはオーバーライドできません。これらの不変ファイルにはファイル名にSHAハッシュが含まれているため、無期限に安全にキャッシュできます。例:Static Image Imports。これらのアセットに対してnext.config.jsでCache-Controlヘッダーを設定することはできません。
ただし、他のレスポンスやデータに対してCache-Controlヘッダーを設定することはできます。
App Routerでのキャッシングの詳細はこちらをご覧ください。
オプション
CORS
Cross-Origin Resource Sharing (CORS)は、どのサイトがリソースにアクセスできるかを制御できるセキュリティ機能です。Access-Control-Allow-Originヘッダーを設定して、特定のオリジンがあなたのリソースにアクセスできるようにすることができます。ルートハンドラー.
async headers() {
return [
{
source: "/api/:path*",
headers: [
{
key: "Access-Control-Allow-Origin",
value: "*", // Set your origin
},
{
key: "Access-Control-Allow-Methods",
value: "GET, POST, PUT, DELETE, OPTIONS",
},
{
key: "Access-Control-Allow-Headers",
value: "Content-Type, Authorization",
},
],
},
];
},X-DNS-Prefetch-Control
このヘッダーはDNSプリフェッチを制御し、ブラウザが外部リンク、画像、CSS、JavaScriptなどのドメイン名解決を積極的に実行できるようにします。このプリフェッチはバックグラウンドで実行されるため、参照されるアイテムが必要になる頃にはDNSが解決される可能性が高くなります。これにより、ユーザーがリンクをクリックしたときの遅延が短縮されます。
{
key: 'X-DNS-Prefetch-Control',
value: 'on'
}Strict-Transport-Security
このヘッダーは、HTTPではなくHTTPSのみを使用してアクセスする必要があることをブラウザに通知します。以下の構成を使用すると、現在および将来のすべてのサブドメインは2年間のmax-ageでHTTPSを使用します。これにより、HTTP経由でのみ提供できるページやサブドメインへのアクセスがブロックされます。
{
key: 'Strict-Transport-Security',
value: 'max-age=63072000; includeSubDomains; preload'
}X-Frame-Options
このヘッダーは、サイトがiframe内で表示されることを許可するかどうかを示します。これはクリックジャッキング攻撃を防ぐのに役立ちます。
このヘッダーはCSPのframe-ancestorsオプションに置き換えられました。これは最新のブラウザでより良いサポートを提供します(構成の詳細についてはContent Security Policyを参照してください)。
{
key: 'X-Frame-Options',
value: 'SAMEORIGIN'
}Permissions-Policy
このヘッダーにより、ブラウザでどの機能とAPIを使用できるかを制御できます。以前はFeature-Policyという名前でした。
{
key: 'Permissions-Policy',
value: 'camera=(), microphone=(), geolocation=(), browsing-topics=()'
}X-Content-Type-Options
このヘッダーは、Content-Typeヘッダーが明示的に設定されていない場合に、ブラウザがコンテンツのタイプを推測しようとするのを防ぎます。これは、ユーザーがファイルをアップロードして共有できるWebサイトのXSS脆弱性を防ぐことができます。
例えば、ユーザーが画像をダウンロードしようとしたが、それが実行可能ファイルのような別のContent-Typeとして扱われ、悪意のあるものになる可能性があります。このヘッダーは、ブラウザ拡張機能のダウンロードにも適用されます。このヘッダーで有効な値はnosniffのみです。
{
key: 'X-Content-Type-Options',
value: 'nosniff'
}Referrer-Policy
このヘッダーは、現在のWebサイト(オリジン)から別のWebサイトへのナビゲーション中にブラウザがどれだけの情報を含めるかを制御します。
{
key: 'Referrer-Policy',
value: 'origin-when-cross-origin'
}Content-Security-Policy
アプリケーションへのContent Security Policyの追加方法については、こちらをご覧ください。
バージョン履歴
| バージョン | 変更履歴 |
|---|---|
v13.3.0 | missingが追加されました。 |
v10.2.0 | hasが追加されました。 |
v9.5.0 | ヘッダーが追加されました。 |
役に立ちましたか?