Join us at JAMstack Conf San Francisco, October 16-18. Register today

The netlify.toml File

TOML is a markup language. The netlify.toml file is your configuration file on how Netlify will build and deploy your site — including redirects, branch and context specific settings, and much more. Its goal is to describe much of your site configuration via code, that you can keep with the code — with two goals:

  • so that when someone forks your repository, they can instantly create a Netlify site using it without having to configure anything in the UI but still get an identical site configuration
  • so that you can track changes in configuration via version control and configure some things that aren’t configurable in our UI

There are other ways to accomplish some of the things you would use the netlify.toml file for. For example, you can use _headers and _redirects files to accomplish what the filename suggests, but having these settings all live in the same file can greatly simplify maintaining them.

Getting Started

The following sections will go through each thing you’ll be able to do in the netlify.toml file and some examples that you could use in your code.

A complete example:

# Settings in the [build] context are global and are applied to all contexts
# unless otherwise overridden by more specific contexts.
  # Directory to change to before starting a build.
  # This is where we will look for package.json/.nvmrc/etc.
  base = "project/"

  # Directory (relative to root of your repo) that contains the deploy-ready
  # HTML files and assets generated by the build. If a base directory has
  # been specified, include it in the publish directory path.
  publish = "project/build-output/"

  # Default build command.
  command = "echo 'default context'"

  # Directory with the serverless Lambda functions to deploy to AWS.
  functions = "project/functions/"

# Production context: all deploys from the Production branch set in your site's
# deploy contexts will inherit these settings.
  publish = "project/output/"
  command = "make publish"
  environment = { ACCESS_TOKEN = "super secret", NODE_VERSION = "8.0.1" }

# Deploy Preview context: all deploys generated from a pull/merge request will
# inherit these settings.
  publish = "project/dist/"

# Here is another way to define context specific environment variables.
  ACCESS_TOKEN = "not so secret"

# Branch Deploy context: all deploys that are not from a pull/merge request or
# from the Production branch will inherit these settings.
  command = "echo branch"
  NODE_ENV = "development"

# Specific branch context: all deploys from this specific branch will inherit
# these settings.
[context.staging] # 'staging' is a branch name
  command = "echo 'staging'"
  base = "staging"

# For contexts of branches with special characters, enclose the branch name
# with quotes.
  command = "echo 'special branch'"
  base = "branch"

# Redirects and headers are GLOBAL for all builds – they do not get scoped to
# contexts no matter where you define them in the file.
# For context-specific rules, use _headers or _redirects files, which are

# A basic redirect rule
  from = "/*"
  to = "/blog/:splat"

# A redirect rule with all the supported properties
  from = "/old-path"
  to = "/new-path"

  # The default HTTP status code is 301, but you can define a different one.
  status = 302

  # By default, redirects won't be applied if there's a file with the same
  # path as the one defined in the `from` property. Setting `force` to `true`
  # will make the redirect rule take precedence over any existing files.
  force = true

  # Redirect from /old-path?id=123 to /new-path. Each combination of query
  # params needs to be defined in a separate [[redirects]] block.
  # More information at
  query = {id = ":id"}

  # Redirect based on browser language, geolocation, and/or identity role.
  conditions = {Language = ["en"], Country = ["US"]}

  # Sign each request with a value defined in an environment variable

  # You can also define custom headers within your redirects blocks.
    X-From = "Netlify"
    X-Api-Key = "some-api-key-string"

# Role-based redirects does not have a 'to' property.
  from = "/gated-path"
  status = 200
  conditions = {Role = ["admin"]}
  force = true

# The following redirect is intended for use with most SPAs that handle
# routing internally.
  from = "/*"
  to = "/index.html"
  status = 200

  # Define which paths this specific [[headers]] block will cover.
  for = "/*"

    X-Frame-Options = "DENY"
    X-XSS-Protection = "1; mode=block"
    Content-Security-Policy = "frame-ancestors"

    # Multi-key header rules are expressed with multi-line strings.
	cache-control = '''

    # Basic-Auth allows you to password protect your whole site.
    # This feature may not be available on all plans.
    Basic-Auth = "someuser:somepassword anotheruser:anotherpassword"

Let’s break it down…

Build Settings

[build] has a number of properties (keys) that you can set. Here’s a list of them:

  • base
  • publish
  • command
  • environment
  • processing

If a key has a list of key/value pairs as its value, you can set that key in its own block like this:

  VARIABLE = "value"

NOTE: If you are setting an environment table for a context (e.g. [context.deploy-preview.environment]), make sure you have the corresponding parent table (e.g. [context.deploy-preview]). Otherwise, the environment variables will not be available.

Deploy Contexts

[context] allows you to set properties based on what kind of deploy it is.

During a build, the following ordering determines which context covers a particular deploy:

  • UI settings are overridden if a netlify.toml file is present in the root folder of the repo and there exists a setting for the same property/redirect/header in the toml file.
  • any property in the [build] key will be applied to all contexts unless the same property key is present in a more specific context.
  • any property in [context.production], [context.deploy-preview] or [context.branch-deploy] will override [build] settings:
    • production — a deploy generated from the production branch set in the UI
    • deploy-preview — a deploy generated from a pull request or merge request
    • branch-deploy — a deploy generated from a branch that is not your production branch
  • any property in [context.branchname], for a given branchname, is the most specific, and thus overrides all the less-specific contexts.

Post processing

You can manage post processing settings with the processing property. These settings override corresponding settings in the site dashboard under Settings > Build & deploy > Post processing > Asset Optimization.

When declaring post processing settings, you can use the processing property on build to define settings for each post processing option. Note that skip_processing must be set to false for any other settings to take effect.

# If skip_processing = true, all other settings are ignored
  skip_processing = false
  bundle = true
  minify = false
  bundle = true
  minify = false
  pretty_urls = true
  compress = true

You can also control post processing settings per deploy context.

# Skip all post processing in deploy previews,
# ignoring any other settings
  skip_processing = true

  skip_processing = false
  compress = false


You can manage your redirects directly in your netlify.toml file. When declaring redirects, use an array of values in a section with the [[redirects]] heading:

  from = "/old-path"
  to = "/new-path"
  status = 301
  force = false
  query = {path = ":path"} #  apply this rule for /old-path?path=example
  conditions = {Language = ["en","es"], Country = ["US"]}

Here’s a proxy redirect:

  from = "/api/*"
  to = ""
  status = 200
  force = true
  conditions = {Role = ["admin", "cms"]}
    X-From = "Netlify"
    X-Api-Key = "some-api-key-string"

You can redirect back to / if the user is unauthorized and gets a 401 status code:

  from = "/api/*"
  to = "/"
  status = 401
  force = true
    X-From = "Netlify"

You can redirect your netlify subdomain to your custom domain. Note that the force = true is equivalent to the ! (for shadowing) in the _redirects file:

  from = ""
  to = ""
  status = 301
  force = true


You can define custom headers like this:

  for = "/*"
    X-Frame-Options = "DENY"
    X-XSS-Protection = "1; mode=block"

    #  Multi-key header rules are expressed with multi-line strings
	cache-control = '''

    # The Basic-Auth header may not be available on all plans.
    Basic-Auth = "someuser:somepassword anotheruser:anotherpassword"


You can set a custom path to your serverless functions:

[build] # Make sure you don't have a duplicate [build] context!
  functions = "myfunctions/"

Calling environment variables

Using environment variables directly as values ($VARIABLENAME) in your netlify.toml file is not supported. However, the following workflow can be used to substitute values in the file with environment variable values, assuming you are only trying to change headers or redirects. The rest of the file is read BEFORE your build — but those sections are read AFTER the build process.

  1. Add a placeholder like HEADER_PLACEHOLDER somewhere in the netlify.toml redirects or headers sections.
  2. Create an environment variable, for example PROD_API_LOCATION, with the desired value. You can create environment variables in the toml file or in our UI. You might use the latter to keep sensitive values out of your repository.
  3. Prepend a replacement command to your build command. Here’s an example for a site using yarn build to build: sed -i s/HEADER_PLACEHOLDER/${PROD_API_LOCATION}/g netlify.toml && yarn build

Netlify Dev

Netlify Dev makes use of the functions block mentioned above, but there is also a new [dev] block for optional further configuration. While Netlify Dev is in beta, you can read through the docs on the Netlify Dev repo.

Notice something is incorrect or outdated?

First off, great catch! We appreciate your discovery and want to ensure it gets addressed immediately. Please let us know here.

Want to have a conversation?

Visit the Netlify Community to discuss ideas and questions with your fellow Netlify users.

Want to get started quick?