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]
ID = "Your_Site_ID"

# Settings in the [build] context are global and are applied to all contexts unless otherwise overridden by more specific contexts.  

[build]
  # This is the directory to change to before starting a build.
  base    = "project/"
  # NOTE: This is where we will look for package.json/.nvmrc/etc, not root.
  # This is the directory that you are publishing from (relative to root of your repo)
  publish = "project/build-output/"
  # This will be your default build command
  command = "echo 'default context'"
  # This is where we will look for your lambda functions
  functions = "project/functions/"

# Production context: All deploys from the Production branch set in your site's deploy settings will inherit these settings.
[context.production]
  publish = "output/"
  command = "make publish"
  environment = { ACCESS_TOKEN = "super secret", NODE_ENV = "8.0.1" }

# Deploy Preview context: All Deploy Previews (https://www.netlify.com/blog/2016/07/20/introducing-deploy-previews-in-netlify/)
# will inherit these settings.
[context.deploy-preview]
  publish = "dist/"
# Here is another way to define context specific environment variables
[context.deploy-preview.environment]
  ACCESS_TOKEN = "not so secret"

# Branch Deploy context: All deploys that are not resulting from a Pull/Merge Request and not from the primary, linked branch will inherit these settings.
[context.branch-deploy]
  command = "echo branch"
[context.branch-deploy.environment]
  NODE_ENV = "development"

# Specific branch context: Deploys from this branch
# will take these settings and override their
# current ones.
[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
[context."feat/branch"]
  command = "echo 'special branch'"
  base = "branch"

# Note that all redirects and headers are GLOBAL for all builds:
# they do not get scoped to contexts no matter where you enter them in the file
# For context-specific rules, use _headers or _redirects - those are PER-DEPLOY.

# A basic redirects rule
[[redirects]]
  from = "/*"
  to = "/blog/:splat"

# The following show an example redirects rule with all the supported properties.
[[redirects]]
  from = "/old-path"
  to = "/new-path"
  status = 301
  force = false
  query = {path = ":path"} # apply this rule for /old-path?path=example
  # NOTE: Each combination of query params will need to be defined in a separate [[redirects]] block. More here: https://www.netlify.com/docs/redirects/#query-params
  conditions = {Language = ["en"], Country = ["US"], Role = ["admin"]}
  # you can use env variables you've set in the UI or within your contexts as values
  # sign each request with the value of this env variable
  signed = "API_SIGNATURE_TOKEN"
  # NOTE: env variables are only natively supported for this signed property of headers via this mechanism!
  # You can also define custom headers within your redirects blocks
  [redirects.headers]
    X-From = "Netlify"
    X-Api-Key = "some-api-key-string"

# The following redirect is intended for use with most SPA's that handles routing internally.
[[redirects]]
  from = "/*"
  to = "/index.html"
  status = 200

[[headers]]
  for = "/*" # This defines which paths this specific [[headers]] block will cover.
  [headers.values]
    X-Frame-Options = "DENY"
    X-XSS-Protection = "1; mode=block"
    Content-Security-Policy = "frame-ancestors https://www.facebook.com"
    # Multi-key header rules are expressed with multi-line strings
    Link = '''
    </assets/css/base.css>; rel=preload; as=style, \
    </assets/css/base2.css>; rel=preload; as=style, \
    </assets/css/base3.css>; rel=preload; as=style'''
    # Basic-Auth allows you to password protect your whole site but is only available
    # to paid accounts
    Basic-Auth = "someuser:somepassword anotheruser:anotherpassword"

Let’s break it down…

Deploy Context

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

  • base
  • publish
  • command
  • environment

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

[build.environment]
  VARIABLE = "value"

[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 - this is the branch that was set in the UI to publish from
    • deploy-preview - a deploy from a Pull Request
    • branch-deploy - a deploy from any Branch
  • any property in [context.branchname], for a given branchname, is the most specific, and thus overrides all the less-specific contexts.

Redirects

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

[[redirects]]
  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:

[[redirects]]
  from = "/api/*"
  to = "https://us-central1-netlify-intercom.cloudfunctions.net/readHeaders/:splat"
  status = 200
  force = true
  conditions = {Role = ["admin", "cms"]}
  [redirects.headers]
    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:

[[redirects]]
  from = "/api/*"
  to = "/"
  status = 401
  force = true
  [redirects.headers]
    X-From = "Netlify"

Headers

You can define custom headers like this:

[[headers]]
  for = "/*"
  [headers.values]
    X-Frame-Options = "DENY"
    X-XSS-Protection = "1; mode=block"

    #  Multi-key header rules are expressed with multi-line strings
    Link = '''
    </style1.css>; rel=preload; as=stylesheet, \
    </style2.css>; rel=preload; as=stylesheet, \
    </style3.css>; rel=preload; as=stylesheet'''

    # The Basic-Auth header is only available on paid plans.
    Basic-Auth = "someuser:somepassword anotheruser:anotherpassword"

Functions

You can set a custom path to your lambda functions:

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

CAVEATS

  • 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 based on environment variables in the file, 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 API_KEY_PLACEHOLDER somewhere in the netlify.toml redirects or headers sections
    2. create an Build Environment Variable, for example API_KEY, with the desired value. You can do this in the toml file or in our UI in the Build and Deploy Settings section of your configuration. You might use the latter to keep sensitive values out of your repository.
    3. add a command like this one to your build command: sed -i s/API_KEY_PLACEHOLDER/$API_KEY/g netlify.toml && normal build command

Notice something is incorrect or outdated?

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

Want to get started quick?