Common Netlify Deployment Mistakes: Don't Forget Your netlify.toml

Don’t Forget Your netlify.toml: A Common Deployment Mistake

If you’ve ever deployed a site to Netlify, you might have encountered this scenario: your site builds perfectly locally, but when you push to Netlify, something isn’t quite right. The build fails, or perhaps it succeeds but your site doesn’t function as expected. After frantically combing through logs and searching for solutions, you realize the issue: you forgot to configure your netlify.toml file.

In this post, I’ll explain why this simple configuration file is critical for successful Netlify deployments and how to set it up correctly for various project types.

What is netlify.toml and Why Does It Matter?

The netlify.toml file is Netlify’s configuration file that defines how your site should be built and deployed. It lives at the root of your project repository and contains important settings like:

  • Build commands
  • Publish directory
  • Environment variables
  • Redirect rules
  • Headers
  • Function configurations
  • And more

Without this file (or with an incorrectly configured one), Netlify may not know how to properly build your site or might make assumptions that don’t align with your project’s requirements.

Common Issues When the netlify.toml is Missing

Here are some common issues you might encounter when your netlify.toml file is missing or incorrectly configured:

  1. Build failures - Netlify doesn’t know what commands to run to build your site
  2. 404 errors - Your site builds but routes aren’t handled correctly
  3. Missing assets - Netlify publishes from the wrong directory
  4. Deployment preview problems - Preview deployments behave differently than production
  5. API or proxy issues - Redirects and rewrites aren’t properly configured

Basic netlify.toml Structure

Here’s a basic netlify.toml file for a typical project:

[build]
  command = "npm run build" # Command to build your site
  publish = "dist"          # Directory to publish (relative to root)
  
[build.environment]
  # Environment variables for all deploy contexts
  NODE_VERSION = "18.16.0"

# Production context: all deploys from the Production branch set in your site's
# deploy contexts will inherit these settings.
[context.production]
  command = "npm run build"
  
# Deploy Preview context: all deploys generated from a pull/merge request will 
# inherit these settings.
[context.deploy-preview]
  command = "npm run build:preview"

[[redirects]]
  from = "/api/*"
  to = "/.netlify/functions/:splat"
  status = 200
  
[[headers]]
  for = "/*"
    [headers.values]
    X-Frame-Options = "DENY"
    X-XSS-Protection = "1; mode=block"

Configuration for Common Frameworks

For Astro Projects

[build]
  command = "npm run build"
  publish = "dist"

[build.environment]
  NODE_VERSION = "18.16.0"

[[redirects]]
  from = "/*"
  to = "/index.html"
  status = 200

For React (Create React App)

[build]
  command = "npm run build"
  publish = "build"

[[redirects]]
  from = "/*"
  to = "/index.html"
  status = 200

For Vue.js (Vue CLI)

[build]
  command = "npm run build"
  publish = "dist"

[[redirects]]
  from = "/*"
  to = "/index.html"
  status = 200

For Next.js

[build]
  command = "npm run build"
  publish = ".next"

[[plugins]]
  package = "@netlify/plugin-nextjs"

Real-World Example: Troubleshooting a Missing netlify.toml

I recently helped a colleague who was deploying an Astro site to Netlify. The site worked perfectly locally, but on Netlify, all the CSS was missing and navigating to any route beyond the homepage resulted in a 404 error.

The problem? The site was missing a netlify.toml file. Netlify was using its default assumptions, which didn’t align with the Astro project structure.

By adding this simple configuration file:

[build]
  command = "npm run build"
  publish = "dist"

[[redirects]]
  from = "/*"
  to = "/index.html"
  status = 200

The deployment immediately started working correctly. The CSS was properly served, and the client-side routing functioned as expected.

Advanced Configuration Options

Once you have the basics working, there’s a lot more you can do with your netlify.toml file:

Environment Variables Based on Context

[context.production.environment]
  API_ENDPOINT = "https://api.example.com/v1"

[context.branch-deploy.environment]
  API_ENDPOINT = "https://staging-api.example.com/v1"

Function Configuration

[functions]
  directory = "functions"
  node_bundler = "esbuild"

Custom Headers for Security

[[headers]]
  for = "/*"
    [headers.values]
    Content-Security-Policy = "default-src 'self'; script-src 'self' https://analytics.example.com;"
    X-Content-Type-Options = "nosniff"
    Referrer-Policy = "strict-origin-when-cross-origin"

Asset Optimization

[build.processing]
  skip_processing = false

[build.processing.css]
  bundle = true
  minify = true

[build.processing.js]
  bundle = true
  minify = true

[build.processing.images]
  compress = true

Making netlify.toml Part of Your Workflow

To avoid forgetting the netlify.toml file in future projects, consider these tips:

  1. Use project templates that include a netlify.toml file by default
  2. Add it to your project checklist when starting new projects
  3. Include it in code reviews to ensure it’s correctly configured
  4. Use local testing with Netlify CLI to catch configuration issues early

Conclusion

The netlify.toml file might seem like a small detail, but it’s crucial for successful deployments on Netlify. By understanding and properly configuring this file, you can avoid many common deployment issues and create a smoother development workflow.

Remember: when in doubt, check your netlify.toml first! It’s often the solution to many mysterious deployment problems.

Have you encountered other issues with Netlify deployments? Let me know in the comments below!

Resources