---
title: "Custom headers"
description: "Define custom headers sent in response to site requests using a _headers file or a netlify.toml file."
---

> For the complete documentation index for AI agents, see [llms.txt](https://docs.netlify.com/llms.txt). Markdown versions of any documentation page are available by appending `.md` to its docs.netlify.com URL.

With custom headers, you can make custom adjustments or additions to the default [HTTP headers](https://developer.mozilla.org/en-US/docs/Glossary/HTTP_header) that Netlify serves with your site when a client makes a request.

You can configure custom headers for your Netlify site in two ways:

- Save a plain text file called `_headers` to the [publish directory](/build/configure-builds/overview#definitions) of your site. You can find [`_headers` file syntax](/manage/routing/headers#syntax-for-the-headers-file) details below.
- Add one or more `headers` tables to your [Netlify configuration file](/build/configure-builds/file-based-configuration#headers). This method allows for more structured configuration and additional capabilities, as described in the [Netlify configuration file syntax](/manage/routing/headers#syntax-for-the-netlify-configuration-file) section below.

## Limitations

- Custom headers apply only to files Netlify serves from our own backing store. If you are [proxying content to your site](/manage/routing/redirects/rewrites-proxies#proxy-to-another-service) or dealing with a URL handled by a [function](/build/functions/overview) or [edge function](/build/edge-functions/overview) such as a server-side rendered (SSR) page, custom headers won't be applied to that content. In those cases, the site being proxied to or the function should return any required headers instead. Visit our docs on edge functions to learn how to [configure `cache-control` headers for edge functions](/build/edge-functions/optional-configuration#response-caching).
- When you declare headers in a `_headers` file stored in the publish directory or a Netlify configuration file, the headers are global for all builds and cannot be scoped for specific branches or deploy contexts. However, there is a workaround you can use to [set unique headers for each deploy context](/manage/routing/headers#custom-headers-for-different-branch-or-deploy-contexts).
- You can set most [HTTP response fields](https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Response_fields) using custom headers. The following header names are exceptions. Custom headers for these are typically ignored because Netlify's web servers need to set these headers to work properly.
  - `Accept-Ranges`
  - `Age`
  - `Allow`
  - `Alt-Svc`
  - `Connection`
  - `Content-Encoding`
  - `Content-Length`
  - `Content-Range`
  - `Date`
  - `Location` - use [redirects](/manage/routing/redirects/overview) instead
  - `Server`
  - `Set-Cookie` - may be overridden by Netlify cookie handling
  - `Trailer`
  - `Transfer-Encoding`
  - `Upgrade`

### Caution - Setting cookies across subdomains only works for custom domains

`netlify.app` is listed in the Mozilla Foundation's [Public Suffix List](http://publicsuffix.org/), which prevents setting cookies across subdomains. You can only set a cookie for all subdomains if your site uses a [custom domain](/manage/domains/get-started-with-domains) instead of `mysitename.netlify.app`.

## Syntax for the `_headers` file

In a `_headers` file, you can specify one or several URL paths with their additional headers indented below them:

- Any line beginning with `#` will be ignored as a comment.
- Header field names are case insensitive.
- Paths can contain [wildcards and placeholders](#wildcards-and-placeholders-in-paths).

Here is an example of a `_headers` file with two URL paths:

```
# a path:
/templates/index.html
  # headers for that path:
  X-Frame-Options: DENY
# another path:
/templates/index2.html
  # headers for that path:
  X-Frame-Options: SAMEORIGIN
```

Here's an example of setting the `X-Frame-Options` header for all pages on your site:

```
/*
  X-Frame-Options: DENY
```

### Caution - Make sure we can access the file

If you're running a build command or site generator, the `_headers` file should end up in the folder you're deploying. Some generators, like Jekyll, may also require additional configuration to avoid exclusion of files that begin with `_`. (For Jekyll, this requires [adding an `include` parameter](https://jekyllrb.com/docs/configuration/options/) to `_config.yml`.)

## Syntax for the Netlify configuration file

If you specify your header rules in your [Netlify configuration file](/build/configure-builds/file-based-configuration#headers), you can use a more structured configuration format with additional capabilities such as [headers for proxy redirects](/manage/routing/redirects/rewrites-proxies#custom-headers-in-proxy-redirects):

- We use [TOML's array of tables](https://toml.io/en/v1.0.0-rc.3#array-of-tables) to specify each individual header rule.
- The following keywords are available:
  - `for`: the path or URL where the headers will be added.
  - `values`: a map of values to add to the response headers.
- Header field names are case insensitive.
- Paths can contain [wildcards and placeholders](#wildcards-and-placeholders-in-paths).

Here's an example:

```toml
[[headers]]
  for = "/*"
  [headers.values]
    X-Frame-Options = "DENY"
```

## Wildcards and placeholders in paths

Whether you declare headers in a dedicated `_headers` file or using the `[[headers]]` section of `netlify.toml`, you can take advantage of wildcards and placeholders in URL path segments:

- Wildcards (`*`) can be used at any place inside of a path segment to match any character.
- Placeholders (`:placeholders`) can only be used at the start of a path segment to match any character except `/`.
- Wildcards and placeholders cannot be within the same path segment.

  For example, `/templates/:placeholder*` won't work as the wildcard is considered part of the placeholder name. `/templates/*:placeholder` won't work as the placeholder needs to be at the beginning of the path segment, right after the `/`.

Note that Netlify processes wildcards and placeholders in redirects differently than those used in headers. Learn more about the options and limitations for [wildcards in splats](/manage/routing/redirects/redirect-options#splats) and [placeholders](/manage/routing/redirects/redirect-options#placeholders) in the [redirect options](/manage/routing/redirects/redirect-options) doc.

## Multi-value headers

Some header fields can accept multiple values.

In a `_headers` file, you can configure multi-value headers by listing multiple headers with the same field name. Netlify will concatenate the values of those headers into a single header as described in the [RFC 7230](https://tools.ietf.org/html/rfc7230#section-3.2).

For example, you can include several `cache-control` header fields in the file, like this:

```
/*
  cache-control: max-age=0
  cache-control: no-cache
  cache-control: no-store
  cache-control: must-revalidate
```

In a `netlify.toml`, multi-value headers are expressed with multiline strings:

```toml
[[headers]]
  for = "/*"
  [headers.values]
  cache-control = '''
  max-age=0,
  no-cache,
  no-store,
  must-revalidate'''
```

In both cases, the values will be collapsed into one header following the HTTP 1.1 specification:

```
cache-control: max-age=0,no-cache,no-store,must-revalidate
```

## Custom headers for different branch or deploy contexts

By default, when you declare headers in a `_headers` file stored in the publish directory or in a Netlify configuration file (`netlify.toml`), the headers are global for all builds and cannot be scoped for specific branches or [deploy contexts](/deploy/deploy-overview#deploy-contexts).

To set custom headers for a specific branch or deploy context:

1. Remove any global header declarations from `netlify.toml` and, if you have one, remove the `_headers` file from the publish directory.
2. Create a new custom directory to store your deploy context-specific header files, such as `/custom-headers`.
3. Create header files for each custom configuration you require and store them in the custom directory. While you can use any file name for each custom file, the files must still follow the [syntax for headers files](#syntax-for-the-headers-file) outlined above.
4. In `netlify.toml`, modify the build command for each deploy context that requires headers. Add the following script to the end of the build command: `&& cp path-to-your-header-file path-to-your-publish-dir/_headers`

   When the build command for the deploy context runs, Netlify will copy the custom header file to a new file named `_headers` in the publish directory for use.

For example, if the custom headers folder is `custom-headers` and you want to apply a specific header file `_stagingHeaders` to your `staging` branch deploys, you would add the following to your `netlify.toml`:

```toml
# Configuration for branch deploys for the branch named `staging`.
# Remember to replace `npm run build` with your site's build command
# and replace `dist` with your site's publish directory.
[context.staging]
  command = "npm run build && cp ./custom-headers/_stagingHeaders ./dist/_headers"
```

Note that in this example, the site uses `npm run build` as the build command and `dist` as the publish directory. You should replace those with the appropriate values for your site.

## Basic authentication headers

> **Pricing Information:** This feature is available on all [Pro](https://www.netlify.com/pricing/?category=developer) and [Enterprise](https://www.netlify.com/pricing/?category=enterprise) plans.

You can configure Netlify to provide [basic authentication](https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication#basic_authentication_scheme) headers on paths you want to hide behind a password.

Visit the [basic authentication](/manage/security/secure-access-to-sites/basic-authentication-with-custom-http-headers) page for more information.
