Movatterモバイル変換


[0]ホーム

URL:


Skip to content
Important
Security Advisory: React2Shell & two new vulnerabilities
Find out more

headers

Last updated April 15, 2025

Headers allow you to set custom HTTP headers on the response to an incoming request on a given path.

To set custom HTTP headers you can use theheaders key innext.config.js:

next.config.js
module.exports= {asyncheaders() {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 is an async function that expects an array to be returned holding objects withsource andheaders properties:

  • source is the incoming request path pattern.
  • headers is an array of response header objects, withkey andvalue properties.
  • basePath:false orundefined - if false the basePath won't be included when matching, can be used for external rewrites only.
  • locale:false orundefined - whether the locale should not be included when matching.
  • has is an array ofhas objects with thetype,key andvalue properties.
  • missing is an array ofmissing objects with thetype,key andvalue properties.

Headers are checked before the filesystem which includes pages and/public files.

Header Overriding Behavior

If two headers match the same path and set the same header key, the last header key will override the first. Using the below headers, the path/hello will result in the headerx-hello beingworld due to the last header value set beingworld.

next.config.js
module.exports= {asyncheaders() {return [      {        source:'/:path*',        headers: [          {            key:'x-hello',            value:'there',          },        ],      },      {        source:'/hello',        headers: [          {            key:'x-hello',            value:'world',          },        ],      },    ]  },}

Path Matching

Path matches are allowed, for example/blog/:slug will match/blog/first-post (no nested paths):

next.config.js
module.exports= {asyncheaders() {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',          },        ],      },    ]  },}

The pattern/blog/:slug matches/blog/first-post and/blog/post-1 but not a nested path like/blog/a/b. Patterns are anchored to the start,/blog/:slug will not match/archive/blog/first-post.

You can use modifiers on parameters:* (zero or more),+ (one or more),? (zero or one). For example,/blog/:slug* matches/blog,/blog/a, and/blog/a/b/c.

Read more details onpath-to-regexp documentation.

Wildcard Path Matching

To match a wildcard path you can use* after a parameter, for example/blog/:slug* will match/blog/a/b/c/d/hello-world:

next.config.js
module.exports= {asyncheaders() {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',          },        ],      },    ]  },}

Regex Path Matching

To match a regex path you can wrap the regex in parenthesis after a parameter, for example/blog/:slug(\\d{1,}) will match/blog/123 but not/blog/abc:

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

The following characters(,),{,},:,*,+,? are used for regex path matching, so when used in thesource as non-special values they must be escaped by adding\\ before them:

next.config.js
module.exports= {asyncheaders() {return [      {// this will match `/english(default)/something` being requested        source:'/english\\(default\\)/:slug',        headers: [          {            key:'x-header',            value:'value',          },        ],      },    ]  },}

Header, Cookie, and Query Matching

To only apply a header when header, cookie, or query values also match thehas field or don't match themissing field can be used. Both thesource and allhas items must match and allmissing items must not match for the header to be applied.

has andmissing items can have the following fields:

  • type:String - must be eitherheader,cookie,host, orquery.
  • key:String - the key from the selected type to match against.
  • value:String orundefined - the value to check for, if undefined any value will match. A regex like string can be used to capture a specific part of the value, e.g. if the valuefirst-(?<paramName>.*) is used forfirst-second thensecond will be usable in the destination with:paramName.
next.config.js
module.exports= {asyncheaders() {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',          },        ],      },    ]  },}

Headers with basePath support

When leveragingbasePath support with headers eachsource is automatically prefixed with thebasePath unless you addbasePath: false to the header:

next.config.js
module.exports= {  basePath:'/docs',asyncheaders() {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,      },    ]  },}

Headers with i18n support

When leveragingi18n support with headers eachsource is automatically prefixed to handle the configuredlocales unless you addlocale: false to the header. Iflocale: false is used you must prefix thesource with a locale for it to be matched correctly.

next.config.js
module.exports= {  i18n: {    locales: ['en','fr','de'],    defaultLocale:'en',  },asyncheaders() {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 sets theCache-Control header ofpublic, max-age=31536000, immutable for truly immutable assets. It cannot be overridden. These immutable files contain a SHA-hash in the file name, so they can be safely cached indefinitely. For example,Static Image Imports. You cannot setCache-Control headers innext.config.js for these assets.

However, you can setCache-Control headers for other responses or data.

If you need to revalidate the cache of a page that has beenstatically generated, you can do so by setting therevalidate prop in the page'sgetStaticProps function.

To cache the response from anAPI Route, you can useres.setHeader:

pages/api/hello.ts
importtype { NextApiRequest, NextApiResponse }from'next'typeResponseData= {  message:string}exportdefaultfunctionhandler(  req:NextApiRequest,  res:NextApiResponse<ResponseData>) {res.setHeader('Cache-Control','s-maxage=86400')res.status(200).json({ message:'Hello from Next.js!' })}

You can also use caching headers (Cache-Control) insidegetServerSideProps to cache dynamic responses. For example, usingstale-while-revalidate.

pages/index.tsx
import { GetStaticProps, GetStaticPaths, GetServerSideProps }from'next'// This value is considered fresh for ten seconds (s-maxage=10).// If a request is repeated within the next 10 seconds, the previously// cached value will still be fresh. If the request is repeated before 59 seconds,// the cached value will be stale but still render (stale-while-revalidate=59).//// In the background, a revalidation request will be made to populate the cache// with a fresh value. If you refresh the page, you will see the new value.exportconstgetServerSideProps= (async (context)=> {context.res.setHeader('Cache-Control','public, s-maxage=10, stale-while-revalidate=59'  )return {    props: {},  }})satisfiesGetServerSideProps

Options

CORS

Cross-Origin Resource Sharing (CORS) is a security feature that allows you to control which sites can access your resources. You can set theAccess-Control-Allow-Origin header to allow a specific origin to access your API Endpoints.

asyncheaders() {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

This header controls DNS prefetching, allowing browsers to proactively perform domain name resolution on external links, images, CSS, JavaScript, and more. This prefetching is performed in the background, so theDNS is more likely to be resolved by the time the referenced items are needed. This reduces latency when the user clicks a link.

{  key:'X-DNS-Prefetch-Control',  value:'on'}

Strict-Transport-Security

This header informs browsers it should only be accessed using HTTPS, instead of using HTTP. Using the configuration below, all present and future subdomains will use HTTPS for amax-age of 2 years. This blocks access to pages or subdomains that can only be served over HTTP.

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

X-Frame-Options

This header indicates whether the site should be allowed to be displayed within aniframe. This can prevent against clickjacking attacks.

This header has been superseded by CSP'sframe-ancestors option, which has better support in modern browsers (seeContent Security Policy for configuration details).

{  key:'X-Frame-Options',  value:'SAMEORIGIN'}

Permissions-Policy

This header allows you to control which features and APIs can be used in the browser. It was previously namedFeature-Policy.

{  key:'Permissions-Policy',  value:'camera=(), microphone=(), geolocation=(), browsing-topics=()'}

X-Content-Type-Options

This header prevents the browser from attempting to guess the type of content if theContent-Type header is not explicitly set. This can prevent XSS exploits for websites that allow users to upload and share files.

For example, a user trying to download an image, but having it treated as a differentContent-Type like an executable, which could be malicious. This header also applies to downloading browser extensions. The only valid value for this header isnosniff.

{  key:'X-Content-Type-Options',  value:'nosniff'}

Referrer-Policy

This header controls how much information the browser includes when navigating from the current website (origin) to another.

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

Content-Security-Policy

Learn more about adding aContent Security Policy to your application.

Version History

VersionChanges
v13.3.0missing added.
v10.2.0has added.
v9.5.0Headers added.

Was this helpful?

supported.

[8]ページ先頭

©2009-2025 Movatter.jp