Alright, let’s talk about getting people from point A to point B on your site, because sometimes you move things, and sometimes the internet just gets lost. We’re diving into Netlify’s two main tools for this: the classic _redirects file and the newer, shinier netlify.toml configuration. They both get the job done, but they have different vibes, like a trusty old wrench versus a multi-tool with a laser level.

First, a crucial piece of wisdom: Netlify handles redirects after your site’s build process. This is different from a framework-level redirect. Your React or Gatsby router might handle a /about-us route, but if that route doesn’t exist in the final built HTML/CSS/JS, the request still hits Netlify’s servers. That’s when Netlify’s redirect engine—powered by either of these methods—kicks in. This is a huge strength; it means you can redirect any incoming path, even ones that never existed in your source code.

The Old Reliable: _redirects File

This is the bedrock. It’s a simple text file you place in your site’s publish directory (often dist, public, or build). Its power lies in its brutal simplicity. Each line is a rule with three space-separated parts: the path you’re requesting, the path you want to go to, and the HTTP status code.

# /netlify/_redirects
/blog/my-old-post    /blog/my-shiny-new-post    301
/store              https://my-old-store.com    302
/newsletter         /.netlify/functions/signup  200

The status code is the secret sauce. A 301 is a permanent move. Tell browsers and Google to update their bookmarks. A 302 is a temporary shift. Use this for A/B tests or seasonal pages. Then there’s the magic trick: the 200 rewrite. This doesn’t redirect the browser’s address bar; it serves the content from the target path as if it were at the requested path. It’s perfect for “masking” a URL, like proxying a serverless function behind a clean path.

The biggest pitfall here? Those spaces are non-negotiable. Use tabs or spaces, but be consistent. A missing space will break the rule silently. It’s infuriating. Also, this file has no concept of environment variables or context-aware logic. It’s a simple, static list.

The Config Power-Up: netlify.toml

For when your redirect needs get more complex, enter netlify.toml. This is a configuration file that lives at the root of your repo. It does a million things, including defining redirects in a more structured, powerful way.

The syntax is more verbose but far more flexible. You define a [[redirects]] table for each rule.

# netlify.toml
[[redirects]]
  from = "/blog/:year/:month/:slug"
  to = "/posts/:year/:month/:slug"
  status = 301

[[redirects]]
  from = "/dash"
  to = "/dashboard"
  status = 301
  force = true

[[redirects]]
  from = "/api/*"
  to = "/.netlify/functions/:splat"
  status = 200

See the immediate benefits? We can use placeholders like :year and :splat (which captures everything after the *) to create dynamic redirect rules. This is where the _redirects file starts to feel like a dinosaur.

The force = true parameter is a killer feature. It tells Netlify to enforce the redirect even if the original file exists. Normally, Netlify will serve a static file if it finds one, ignoring the redirect rule. force overrides that. This is crucial for when you want to redirect a path like /admin to a different service, even if you accidentally have an admin.html file lurking in your build folder.

Splats, Placeholders, and Gotchas

Both methods support splats (*) and placeholders, but the syntax differs slightly. In _redirects, a * captures everything, and you reference it with :splat in the to path.

# _redirects file
/old/*  /new/:splat  301

In netlify.toml, you use * in the from and :splat in the to.

# netlify.toml
[[redirects]]
  from = "/old/*"
  to = "/new/:splat"
  status = 301

A common “oh crap” moment is the order of operations. Netlify evaluates redirects from top to bottom, first in _redirects, then in netlify.toml. The first matching rule wins. So if you have a super broad rule like /* at the top of your file, nothing below it will ever run. Always put your most specific rules first and your catch-alls at the very bottom.

So, Which One Should You Use?

My general rule of thumb:

  • Use _redirects for simple, one-off redirects. It’s quick, easy, and lives right next to your built files.
  • Use netlify.toml for anything complex. If you need environment-specific redirects, are using splats heavily, require the force parameter, or just want to keep all your Netlify config (redirects, headers, build settings) in one central file, this is the way.

You can even use both simultaneously, but for the sake of your sanity and anyone else who has to read your code, just pick one. You have the power to route traffic with surgical precision. Use it wisely, test it thoroughly (netlify dev is your friend), and never let a user see a 404 you could have turned into a helpful detour.