The netlify.toml file is not just a configuration file; it’s the central nervous system for your Netlify deployments, allowing you to define everything from build commands to redirects and environment variables, all version-controlled alongside your code.
Let’s see it in action. Imagine you have a static site generator project, say Hugo, and you want to deploy it to Netlify. Your netlify.toml might look like this:
[build]
command = "hugo --gc --minify"
publish = "public"
[functions]
node_version = "18"
[dev]
command = "hugo server -D"
targetPort = 1313
functionsPort = 8888
[[redirects]]
from = "/old-path"
to = "/new-path"
status = 301
[[headers]]
for = "/*"
[headers.values]
X-Frame-Options = "DENY"
X-XSS-Protection = "1; mode=block"
This simple file tells Netlify exactly how to build your site (hugo --gc --minify), where to find the built assets (public), which Node.js version to use for serverless functions (18), how to run it locally for development (hugo server -D), and even defines a 301 redirect and some custom headers.
The core problem netlify.toml solves is the disconnect between your local development environment and your production deployment. Without it, you’d be manually configuring build settings, environment variables, and redirects in the Netlify UI, which is error-prone and doesn’t scale. By centralizing this in netlify.toml, you achieve:
- Reproducible Builds: Anyone cloning your repo gets the exact same build setup.
- Version Control: Your deployment configuration evolves with your code.
- Local Development Parity: The
[dev]section ensures your local server mimics production as closely as possible. - Advanced Features: Easily configure redirects, rewrites, headers, and more.
Let’s break down the key sections:
The [build] section is where the magic happens for your production deployment.
command: This is the shell command Netlify will execute to build your project. For a React app using Create React App, this might benpm run build. For a Gatsby site, it’s oftengatsby build. Netlify runs this in a clean container, so it needs to be self-contained.publish: This specifies the directory Netlify should deploy. It’s the output of your build command. For most static site generators, this is adist,build, orpublicfolder.environment: You can define environment variables here that are only available during the build process. This is useful for API keys or secrets needed to fetch data during the build.
The [functions] section configures Netlify Functions, which are serverless functions.
node_version: Specifies the Node.js version for your functions. This is crucial for compatibility. If you’re using newer Node.js features, you’ll need to set this accordingly, e.g.,node_version = "20".directory: If your functions are not in the rootnetlify/functionsdirectory, you can specify their location here.
The [dev] section is a game-changer for local development. It tells Netlify’s Dev CLI how to run your site locally.
command: The command to start your local development server. For Vite, this might benpm run dev.targetPort: The port your development server runs on. Netlify Dev will proxy to this.functionsPort: The port your Netlify Functions will run on locally.
The [[redirects]] and [[headers]] sections allow you to manage routing and response headers directly in your TOML file.
fromandto: Define the source path and destination path for redirects.status: The HTTP status code for the redirect (e.g.,200for a rewrite,301for a permanent redirect,302for a temporary redirect).for: Specifies which paths the headers apply to.headers.values: A map of header names and their values.
When Netlify Dev runs, it reads this netlify.toml file to set up your local environment. It starts your development server on the targetPort, your functions on the functionsPort, and then proxies requests to your site. This means you can test redirects, function routes, and build logic locally before pushing to production.
A lesser-known but powerful feature is the ability to define plugins directly within netlify.toml. These are Netlify-specific or community-built plugins that can extend build functionality without you needing to write complex custom scripts. For example, you might use a plugin to optimize images during the build or to inject analytics code. You’d declare them like this:
[[plugins]]
package = "@netlify/plugin-image-optim"
This allows for a highly modular and extensible build process, directly managed within your project’s configuration.
Once you’ve got your netlify.toml sorted, the next logical step is to explore advanced routing patterns using Edge Functions for more dynamic, edge-computed responses.