Menu

ヘッダー

ヘッダーを使用すると、特定のパスへの受信リクエストに対するレスポンスにカスタム HTTP ヘッダーを設定できます。

カスタム HTTP ヘッダーを設定するには、next.config.jsheaders キーを使用します:

next.config.js
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 は、sourceheaders プロパティを持つオブジェクトを含む配列を返す非同期関数です:

  • source は、受信リクエストのパスパターンです。
  • headers は、keyvalue プロパティを持つレスポンスヘッダーオブジェクトの配列です。
  • basePath: false または undefined - false の場合、マッチング時にベースパスは含まれません。外部リライトにのみ使用できます。
  • locale: false または undefined - ロケールをマッチング時に含めないかどうか。
  • has は、typekeyvalue プロパティを持つhasオブジェクトの配列です。
  • missing は、typekeyvalue プロパティを持つmissingオブジェクトの配列です。

ヘッダーは、ページや /public ファイルを含むファイルシステムの前にチェックされます。

ヘッダーの上書き動作

同じパスで同じヘッダーキーを設定する2つのヘッダーがある場合、最後のヘッダーキーが最初のヘッダーを上書きします。以下のヘッダーを使用すると、パス /hello は、最後に設定されたヘッダー値が world であるため、ヘッダー x-helloworld となります。

next.config.js
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 に一致します(ネストされたパスは含まれません):

next.config.js
module.exports = {
  async headers() {
    return [
      {
        source: '/blog/:slug',
        headers: [
          {
            key: 'x-slug',
            value: ':slug', // マッチしたパラメータを値で使用できます
          },
          {
            key: 'x-slug-:slug', // マッチしたパラメータをキーで使用できます
            value: 'my other custom header value',
          },
        ],
      },
    ]
  },
}

ワイルドカードパスの一致

ワイルドカードパスを一致させるには、パラメータの後に * を使用します。例えば /blog/:slug*/blog/a/b/c/d/hello-world に一致します:

next.config.js
module.exports = {
  async headers() {
    return [
      {
        source: '/blog/:slug*',
        headers: [
          {
            key: 'x-slug',
            value: ':slug*', // マッチしたパラメータを値で使用できます
          },
          {
            key: 'x-slug-:slug*', // マッチしたパラメータをキーで使用できます
            value: 'my other custom header value',
          },
        ],
      },
    ]
  },
}

正規表現パスの一致

正規表現パスを一致させるには、パラメータの後に括弧で正規表現を囲みます。例えば /blog/:slug(\\d{1,})/blog/123 に一致しますが、/blog/abc には一致しません:

next.config.js
module.exports = {
  async headers() {
    return [
      {
        source: '/blog/:post(\\d{1,})',
        headers: [
          {
            key: 'x-post',
            value: ':post',
          },
        ],
      },
    ]
  },
}

(, ), {, }, :, *, +, ? の文字は、正規表現パスの一致に使用されるため、source で特殊でない値として使用する場合は、それらの前に \\ を追加してエスケープする必要があります:

next.config.js
module.exports = {
  async headers() {
    return [
      {
        // これは `/english(default)/something` のリクエストに一致します
        source: '/english\\(default\\)/:slug',
        headers: [
          {
            key: 'x-header',
            value: 'value',
          },
        ],
      },
    ]
  },
}

ヘッダー、クッキー、およびクエリの一致

ヘッダー、クッキー、またはクエリ値も has フィールドに一致する場合、またはフィールドに一致しない missing フィールドのみにヘッダーを適用できます。ヘッダーを適用するには、source とすべての has アイテムが一致し、すべての missing アイテムが一致しない必要があります。

hasmissing アイテムには、以下のフィールドを使用できます:

  • type: String - headercookiehost、または query のいずれかである必要があります。
  • key: String - 選択されたタイプから一致させるキー。
  • value: String または undefined - チェックする値。未定義の場合、任意の値に一致します。値の特定の部分をキャプチャするために、正規表現のような文字列を使用できます。例えば、値 first-(?<paramName>.*)first-second に使用すると、:paramName で宛先で second を使用できます。
next.config.js
module.exports = {
  async headers() {
    return [
      // ヘッダー `x-add-header` が存在する場合、
      // `x-another-header` ヘッダーが適用されます
      {
        source: '/:path*',
        has: [
          {
            type: 'header',
            key: 'x-add-header',
          },
        ],
        headers: [
          {
            key: 'x-another-header',
            value: 'hello',
          },
        ],
      },
      // ヘッダー `x-no-header` が存在しない場合、
      // `x-another-header` ヘッダーが適用されます
      {
        source: '/:path*',
        missing: [
          {
            type: 'header',
            key: 'x-no-header',
          },
        ],
        headers: [
          {
            key: 'x-another-header',
            value: 'hello',
          },
        ],
      },
      // ソース、クエリ、クッキーが一致する場合、
      // `x-authorized` ヘッダーが適用されます
      {
        source: '/specific/:path*',
        has: [
          {
            type: 'query',
            key: 'page',
            // 値が提供され、名前付きキャプチャグループを使用しないため、
            // ページ値はヘッダーキー/値で使用できません(例:(?<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',
          },
        ],
      },
      // ホストが `example.com` の場合、
      // このヘッダーが適用されます
      {
        source: '/:path*',
        has: [
          {
            type: 'host',
            value: 'example.com',
          },
        ],
        headers: [
          {
            key: 'x-another-header',
            value: ':authorized',
          },
        ],
      },
    ]
  },
}

basePath サポート付きのヘッダー

basePath サポートでヘッダーを活用する場合、basePath: false を追加しない限り、各 source は自動的に basePath で接頭辞が付けられます:

next.config.js
module.exports = {
  basePath: '/docs',
 
  async headers() {
    return [
      {
        source: '/with-basePath', // /docs/with-basePath になります
        headers: [
          {
            key: 'x-hello',
            value: 'world',
          },
        ],
      },
      {
        source: '/without-basePath', // basePath: false が設定されているため、変更されません
        headers: [
          {
            key: 'x-hello',
            value: 'world',
          },
        ],
        basePath: false,
      },
    ]
  },
}

i18n対応のヘッダー

i18nサポートを利用する場合、各sourceは設定されたlocalesを処理するために自動的に接頭辞が付けられます。ただし、ヘッダーにlocale: falseを追加した場合は除きます。locale: falseを使用する場合、正しく一致させるためにはソースにロケールを接頭辞として付ける必要があります。

next.config.js
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` であるため、'/'に一致する
        source: '/en',
        locale: false,
        headers: [
          {
            key: 'x-hello',
            value: 'world',
          },
        ],
      },
      {
        // これは /(en|fr|de)/(.*) に変換されるため、/:path* のようなトップレベルの
        // `/` または `/fr` ルートとは一致しない
        source: '/(.*)',
        headers: [
          {
            key: 'x-hello',
            value: 'world',
          },
        ],
      },
    ]
  },
}

Cache-Control

Next.jsは、完全に変更されない静的アセットに対してpublic, max-age=31536000, immutableCache-Controlヘッダーを設定します。これは上書きできません。これらの変更不可能なファイルには、ファイル名にSHA-ハッシュが含まれているため、無期限に安全にキャッシュできます。例えば、静的画像のインポートなどです。これらのアセットに対してnext.config.jsCache-Controlヘッダーを設定することはできません。

ただし、他のレスポンスやデータに対してCache-Controlヘッダーを設定することはできます。

App Routerでのキャッシュについて詳しく学ぶ。

オプション

CORS

クロスオリジンリソース共有(CORS)は、どのサイトがリソースにアクセスできるかを制御できるセキュリティ機能です。Access-Control-Allow-Originヘッダーを設定して、特定のオリジンにルートハンドラーへのアクセスを許可できます。

async headers() {
    return [
      {
        source: "/api/:path*",
        headers: [
          {
            key: "Access-Control-Allow-Origin",
            value: "*", // オリジンを設定
          },
          {
            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年間HTTPSを使用します。これにより、HTTPでのみ提供できるページまたはサブドメインへのアクセスがブロックされます。

Vercelにデプロイする場合、next.config.jsheadersを宣言しない限り、このヘッダーは自動的に追加されるため、必要ありません。

{
  key: 'Strict-Transport-Security',
  value: 'max-age=63072000; includeSubDomains; preload'
}

X-Frame-Options

このヘッダーは、サイトをiframe内に表示できるかどうかを示します。これはクリックジャッキング攻撃を防ぐことができます。

このヘッダーは、最新のブラウザでより優れたサポートを持つCSPのframe-ancestorsオプションに置き換えられています(詳細はコンテンツセキュリティポリシーの設定を参照)。

{
  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サイト(オリジン)から別のサイトに移動する際に、ブラウザが含める情報の量を制御します。

{
  key: 'Referrer-Policy',
  value: 'origin-when-cross-origin'
}

Content-Security-Policy

アプリケーションにコンテンツセキュリティポリシーを追加する方法について詳しく学びます。

バージョン履歴

バージョン変更点
v13.3.0missing が追加されました。
v10.2.0has が追加されました。
v9.5.0ヘッダーが追加されました。