File-based configuration
In addition to using the Netlify UI to configure build settings, deploy settings, and environment variables, you can also configure these settings in a netlify.toml
file.
The file is normally stored in the root of your site repository, but you can include a netlify.toml
at multiple levels for special cases like monorepos. Settings specified in netlify.toml
override any corresponding UI settings.
The netlify.toml
is a configuration file that specifies how Netlify builds and deploys your site — including redirects, branch and context-specific settings, and more. Its goal is to describe much of your site configuration alongside your code — with two goals:
- When someone forks your repository, they can instantly create a Netlify site using the new repo. They don’t have to configure anything in the UI, and they’ll still get an identical site configuration.
- You can track configuration changes using version control and configure some things that aren’t customizable in our UI.
There are other ways to accomplish some of the things you would use the netlify.toml
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.
The following sections will go through each thing you’ll be able to do in the netlify.toml
and some examples that you could use in your code. For more information on TOML syntax, visit the TOML website.
# Sample netlify.toml
file
This sample file demonstrates many settings available for configuration in netlify.toml
.
# Settings in the [build] context are global and are applied to
# all contexts unless otherwise overridden by more specific contexts.
[build]
# Directory to change to before starting a build.
# This is where we will look for package.json/.nvmrc/etc.
# If not set, defaults to the root directory.
base = "project/"
# Directory that contains the deploy-ready HTML files and
# assets generated by the build. This is relative to the base
# directory if one has been set, or the root directory if
# a base has not been set. This sample publishes the directory
# located at the absolute path "root/project/build-output"
publish = "build-output/"
# Default build command.
command = "echo 'default context'"
[[plugins]]
# Installs the Lighthouse Build Plugin for all deploy contexts
package = "@netlify/plugin-lighthouse"
# Production context: all deploys from the Production branch
# set in your site’s Branches settings in the UI will inherit
# these settings. You can define environment variables
# here but we recommend using the Netlify UI for sensitive
# values to keep them out of your source repository.
[context.production]
publish = "output/"
command = "make publish"
environment = { NODE_VERSION = "14.15.3" }
# Deploy Preview context: all deploys generated from
# a pull/merge request will inherit these settings.
[context.deploy-preview]
publish = "dist/"
# Here is an example of how to define context-specific
# environment variables. Be mindful when using this
# option and avoid committing sensitive values to public
# source repositories.
[context.deploy-preview.environment]
NOT_PRIVATE_ITEM = "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.
[context.branch-deploy]
command = "echo branch"
[context.branch-deploy.environment]
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.
[context."feat/branch"]
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 PER-DEPLOY.
# A basic redirect rule
[[redirects]]
from = "/*"
to = "/blog/:splat"
# A redirect rule with many of the supported properties
[[redirects]]
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 https://docs.netlify.com/routing/redirects/redirect-options/#query-parameters
query = {id = ":id"}
# Redirect based on conditions including browser language,
# geolocation, identity role, and/or cookie presence.
conditions = {Language = ["en"], Country = ["US"]}
# Sign each request with a value defined in an environment variable
signed = "API_SIGNATURE_TOKEN"
# You can also define custom headers within your redirects blocks.
[redirects.headers]
X-From = "Netlify"
X-Api-Key = "some-api-key-string"
# Role-based redirects do not have a “to” property.
[[redirects]]
from = "/gated-path"
status = 200
conditions = {Role = ["admin"]}
force = true
# The following redirect is intended for use with most SPAs
# that handle routing internally.
[[redirects]]
from = "/*"
to = "/index.html"
status = 200
[[headers]]
# Define which paths this specific [[headers]] block will cover.
for = "/*"
[headers.values]
X-Frame-Options = "DENY"
X-XSS-Protection = "1; mode=block"
Content-Security-Policy = "frame-ancestors https://www.facebook.com"
# Multi-value headers are expressed with multi-line strings.
cache-control = '''
max-age=0,
no-cache,
no-store,
must-revalidate'''
# 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"
[functions]
# Directory with serverless functions, including background
# functions, to deploy. This is relative to the base directory
# if one has been set, or the root directory if
# a base hasn’t been set.
directory = "functions/"
# An Edge Handler declaration
[[edge_handlers]]
path = "/*"
handler = "filterRequests"
# Configuration details
The following sections provide additional detail for some commonly used configuration settings.
# Build settings
The [build]
command runs in the Bash shell, allowing you to add Bash-compatible syntax to the command. Netlify also supports these properties (keys) for the [build]
command:
base
publish
command
environment
processing
edge_handlers
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"
# Ignore builds
Netlify tries to determine if there are any changes in the site’s base directory by comparing the last known version of the files within that directory. If no change is detected, the build system skips the build, returning early from the build process.
To override the default check with a custom workflow, you can use the ignore
attribute in netlify.toml
. This allows you to specify a Bash or Node.js command to determine whether the site needs rebuilding or not.
Check out our ignore builds doc for more information on the default ignore behavior and details about constructing a custom ignore
command.
# Build Plugins
Netlify Build Plugins extend the functionality of the build process. In addition to installing plugins in the UI, you can also add them to a site using file-based installation. Here's an example [[plugins]]
section in netlify.toml
:
[[plugins]]
package = "netlify-plugin-check-output-for-puppy-references"
[plugins.inputs]
breeds = ["pomeranian", "chihuahua", "bulldog"]
For more detailed information about installation, configuration options, and building and sharing different types of plugins, check out our Build Plugins docs.
# Deploy contexts
Certain keys, such as [build]
and [[plugins]]
but not [[redirects]]
or [[headers]]
, allow you to set [context]
properties based on the kind of deploy. These keys are context-aware.
During a build, the following ordering determines which context covers a particular deploy:
- UI settings are overridden if a
netlify.toml
file is present and a setting for the same property/redirect/header exists in the UI and the TOML file. - any property of a context-aware key, such as
[build]
or[[plugins]]
, 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 less specific contexts:- production — a deploy generated from the production branch set in the UI under Site settings > Build & deploy > Continuous Deployment > Branches
- 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 under Site 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
[build.processing]
skip_processing = false
[build.processing.css]
bundle = true
minify = false
[build.processing.js]
bundle = true
minify = false
[build.processing.html]
pretty_urls = true
[build.processing.images]
compress = true
You can also control post processing settings per deploy context.
# Skip all post processing in deploy previews,
# ignoring any other settings
[context.deploy-preview.processing]
skip_processing = true
[context.branch-name.processing]
skip_processing = false
[context.branch-name.processing.images]
compress = false
# Redirects
You can manage your redirects directly in your netlify.toml
. For each redirect you want to declare, add an entry 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"]}
[[redirects]]
from = "/news"
to = "/blog"
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 your netlify subdomain to your custom domain. Note that the force = true
is equivalent to the !
(for shadowing) in the _redirects
file:
[[redirects]]
from = "https://somenetlifysite.netlify.app"
to = "https://mycustomdomain.com"
status = 301
force = true
# Headers
You can define custom headers in netlify.toml
. Here is an example of some headers you could configure:
[[headers]]
for = "/*"
[headers.values]
X-Frame-Options = "DENY"
X-XSS-Protection = "1; mode=block"
# Multi-value headers are expressed with multi-line strings
cache-control = '''
max-age=0,
no-cache,
no-store,
must-revalidate'''
# The Basic-Auth header may not be available on all plans.
Basic-Auth = "someuser:somepassword anotheruser:anotherpassword"
# Functions
Although there are default settings for Netlify Functions to help you get started, you can use the [functions]
section in netlify.toml
for optional, custom configuration.
The following property applies for all functions:
directory
: custom path to your functions. The default location isYOUR_BASE_DIRECTORY/netlify/functions
.
Meanwhile, the following properties apply only for functions written in JavaScript or TypeScript. You can set them for all functions in your project or filter them by name, including using glob patterns. If a function matches several configuration blocks containing one of these properties, the values are concatenated.
node_bundler
: function bundling method used in @netlify/zip-it-and-ship-it. Valid values:zisi
: default function bundling method for JavaScript functions.esbuild
: method that leverages esbuild to bundle functions, resulting in shorter bundling times and smaller artifacts. Currently available as an opt-in beta for JavaScript functions. TypeScript functions always useesbuild
.
external_node_modules
: list of Node.js modules that are copied to the bundled artifact without adjusting their source or references during the bundling process; only applies whennode_bundler
is set toesbuild
. This property helps handle dependencies that can’t be inlined, such as modules with native add-ons.included_files
: list of additional paths to include in the function bundle. Although our build system includes statically referenced files (likerequire("./some-file.js")
) by default,included_files
lets you specify additional files or directories and reference them dynamically in function code. You can use*
to match any character or prefix an entry with!
to exclude files. Paths are relative to the base directory.For more context, check out our blog post about including files in Netlify Functions with caveats for the
esbuild
bundler.
[functions]
# Sets a custom directory for Netlify Functions
directory = "myfunctions/"
# Specifies `esbuild` for functions bundling
node_bundler = "esbuild"
# Flags "package-1" as an external node module for all functions
external_node_modules = ["package-1"]
# Includes all Markdown files inside the "files/" directory.
included_files = ["files/*.md"]
[functions."api_*"]
# Flags "package-2" as an external node module for functions
# with a name beginning with "api_". Functions matching this
# pattern have both "package-1" and "package-2" as
# external modules, because modules from this object
# are concatenated with any from the top-level object.
external_node_modules = ["package-2"]
# Includes all Markdown files previously defined in the
# top-level object, except for "post-1.md".
included_files = ["!files/post-1.md"]
[functions.api_payment]
# Flags "package-3" and "package-4" as external node modules
# for a function named "api_payment".
# This function has 4 external node modules:
# "package-1" from the top-level object
# "package-2" from the "api_*" object
# "package-3" and "package-4" from this object
external_node_modules = ["package-3", "package-4"]
# Includes all Markdown files inside "files/", except for
# "post-1.md" (excluded in the "api_*" object)
# and "post-2.md" (excluded in this object).
# Also includes "package.json" and any files
# inside "images/" or any of its subdirectories.
included_files = ["!files/post-2.md", "package.json", "images/**"]
# Edge Handlers
To declare an Edge Handler, use an entry with the [[edge_handlers]]
heading:
[[edge_handlers]]
path = "/my/path"
handler = "myHandler"
You can use the [build]
setting to set a custom path to your Edge Handlers directory. If not set, we default to YOUR_BASE_DIRECTORY/netlify/edge-handlers
.
[build] # Make sure you don’t have a duplicate [build] context!
edge_handlers = "src/my-edge-handlers"
The path is either relative to the root of the repository, or, if a base directory is set, it’s relative to the base directory.
# Netlify Dev
Netlify Dev uses detectors to enable a local development environment for most tools and frameworks without any additional setup.
You can use the [dev]
section in netlify.toml
for optional configuration. Note that [dev]
doesn’t run in the Bash shell, however, so you won’t be able to use Bash-compatible syntax with the command.
Netlify Dev also makes use of the functions directory setting to scaffold and serve your functions in a local development environment.
[dev]
includes optional properties such as these:
command
: command that starts your development server or runs a command such as a compiler watch in the background. If notargetPort
is specified, it runs the command in the background in addition to the static file server.port
: port that Netlify Dev is accessible from in the browser.targetPort
: port for your application server, framework, or site generator. If provided, the CLI will wait until the providedtargetPort
is reachable and then proxy requests to it. If you specify values for bothcommand
andtargetPort
,framework
must be#custom
.functionsPort
: the port where Netlify Dev serves functions.publish
: path to your static content folder.jwtRolePath
: object path that points to role values for JWT-based redirects.jwtSecret
: secret used to verify tokens for JWT-based redirects.autoLaunch
: boolean value that determines whether Netlify Dev launches the local server address in your browser.framework
: setting to use if a project is detected incorrectly, flagged by multiple detectors, or requires acommand
andtargetPort
. Valid values:#auto
: default, tests all available detectors.#static
: property that specifies a static file server.#custom
: property that uses thecommand
value to run an app server and thetargetPort
value to connect to it. Required ifcommand
andtargetPort
are both set.
https
: property that specifies an SSL/TLS certificate and key file for the Netlify Dev local server. By default, Netlify Dev starts an HTTP server, but you can configure a certificate and key file if you require HTTPS. Thehttps
configuration is an object with the following properties:certFile
: path to the certificate file.keyFile
: path to the private key file.
Here’s an example [dev]
section for Netlify Dev configuration overrides:
[dev]
command = "yarn start"
port = 8888
targetPort = 3000
publish = "dist"
jwtRolePath = "app_metadata.authorization.roles"
jwtSecret = "MY_JWT_SECRET_VALUE"
autoLaunch = true
framework = "#custom"
[dev.https]
certFile = "cert.pem"
keyFile = "key.pem"
# Inject environment variable values
Using environment variables directly as values in your netlify.toml
, for example key = "$VARIABLENAME"
, isn’t supported.
You can, however, use environment variables in any Bash command (such as the [build]
command
and ignore
command but not the [dev]
command
). This means you can use the [build]
command
, as outlined in the following workflow, to substitute values in the file with environment variable values, assuming you are only trying to change headers, redirects, or Edge Handlers. Although the rest of the netlify.toml
is read before your build, [[headers]]
, [[redirects]]
, and [[edge_handlers]]
sections are read after the build process.
Add a placeholder like
HEADER_PLACEHOLDER
somewhere in the[[headers]]
,[[redirects]]
, or[[edge_handlers]]
sections of your TOML file.Create an environment variable, for example
PROD_API_LOCATION
, with the desired value in the Netlify UI. You may also use your TOML file to create the variable but we recommend you use the UI instead to keep sensitive values out of your repository.Prepend a replacement
sed
command to your build command. Thesed
command must use double quotation marks, not single ones. Here’s an example for a site usingyarn build
to build:[build] command = "sed -i \"s|HEADER_PLACEHOLDER|${PROD_API_LOCATION}|g\" netlify.toml && yarn build"
Did you find this doc useful?
Your feedback helps us improve our docs.