Netlify’s netlify.toml file is your secret weapon for controlling every aspect of your deployments, from build commands to redirects and environment variables.
Let’s see it in action. Imagine you’re deploying a React app. Your netlify.toml might look like this:
[build]
command = "npm run build"
publish = "build"
[functions]
node_version = "18"
[dev]
command = "npm start"
targetPort = 3000
framework = "react"
[[redirects]]
from = "/old-path"
to = "/new-path"
status = 301
This config tells Netlify:
- To run
npm run buildto create your site’s static assets. - To look for those assets in the
builddirectory. - To use Node.js version 18 for any serverless functions you deploy.
- To start your local development server with
npm startand expect it on port 3000, recognizing it as a React app. - To permanently redirect any traffic to
/old-pathto/new-path.
The netlify.toml file is a TOML (Tom’s Obvious, Minimal Language) configuration file that lives in the root of your Git repository. Netlify automatically detects and uses it when you deploy. It’s the single source of truth for your deployment settings, overriding most UI configurations.
The [build] section is fundamental. Here, command specifies the script to run to build your project. This is crucial for frameworks like React, Vue, or Gatsby, which need a build step to generate static HTML, CSS, and JavaScript. publish tells Netlify which directory contains the output of your build command. If this is incorrect, you’ll likely see a blank page or a "File not found" error.
The [functions] section is for Netlify Functions, which are serverless functions. node_version specifies which Node.js runtime to use for these functions. This is important for compatibility with specific Node.js modules or features.
The [dev] section is purely for local development using the Netlify CLI. command is the command to start your local development server, and targetPort is the port it runs on. framework helps the CLI optimize the local dev experience.
The [[redirects]] section is for defining URL redirects. The from path is the incoming URL, and to is the destination. status is the HTTP status code for the redirect; 301 is a permanent redirect, 302 is temporary. This is invaluable for SEO when you change URLs or for handling old links.
You can also define environment variables directly in netlify.toml within the [build.environment] section. This is useful for API keys or other secrets needed during the build process, though for sensitive secrets, Netlify’s UI is generally preferred for better security.
[build]
command = "yarn build"
publish = "dist"
[build.environment]
NODE_ENV = "production"
MY_API_KEY = "your_build_time_api_key" # Use with caution for sensitive data
This configuration changes the build command to yarn build and sets the publish directory to dist. It also sets build-time environment variables NODE_ENV to production and MY_API_KEY.
One powerful, yet often overlooked, aspect of netlify.toml is its ability to define different configurations based on the Git branch being deployed. This is achieved using the [context.<context-name>] syntax. For instance, you might have a separate build command or environment variables for your staging branch.
[build]
command = "npm run build:prod"
publish = "dist"
[context.deploy-preview]
command = "npm run build:preview"
[context.branch-deploy]
command = "npm run build:staging"
publish = "staging-dist"
[context.branch-deploy.environment]
API_URL = "https://staging.api.example.com"
In this example:
- The default deploy (e.g., from your main branch) uses
npm run build:prodand publishes todist. - Deploy Previews (from pull requests) use
npm run build:preview. - Branch Deploys (e.g., from a
stagingbranch) usenpm run build:staging, publish tostaging-dist, and set a specificAPI_URLfor staging.
You can also define headers and edge functions within netlify.toml. For example, to set custom security headers:
[[headers]]
for = "/*"
[headers.values]
X-Frame-Options = "DENY"
X-XSS-Protection = "1; mode=block"
Referrer-Policy = "strict-origin-when-cross-origin"
[[edge_functions]]
function = "my-edge-function"
path = "/api/*"
This configuration applies specific HTTP headers to all requests (/*) and deploys an edge function named my-edge-function to handle requests starting with /api/.
The most surprising true thing about netlify.toml is how granularly you can control specific files or paths within the [redirects] and [[headers]] sections, going far beyond simple glob patterns. For instance, you can apply different headers to specific image files versus HTML files, or create complex redirect chains that Netlify’s edge network handles efficiently.
The next concept you’ll likely encounter is managing Netlify’s cache to speed up builds.