
How to Set Up Redirects in Netlify (_redirects File and netlify.toml)
Redirects are one of those things you don't think about until you really need them. You've renamed a URL and Google still links to the old one. You're migrating from another platform and all the paths changed. You want /github to point to your repo because the full URL is impossible to remember.
Netlify's redirect system is surprisingly powerful for what looks like a simple config file. You can do basic URL redirects, pattern matching with wildcards, rewrites for SPAs, proxy rules, and even country-based routing. Here's how to use all of it.
Redirects vs. rewrites
Quick distinction before we dive in:
A redirect tells the browser "go here instead." The URL in the address bar changes. You get an HTTP 301 or 302 status code.
A rewrite serves different content without changing the URL. The visitor doesn't know anything happened. You get an HTTP 200 status code.
Netlify uses the same syntax for both. The difference is just the status code.
Where to put your redirects
Two options:
A _redirects file
A plain text file in your publish directory (the folder Netlify deploys — usually public/, dist/, or build/).
/old-page /new-page 301
Simple, easy to read, and works great for small projects.
netlify.toml
If you prefer everything in one config file:
[[redirects]]
from = "/old-page"
to = "/new-page"
status = 301
Same result, just different syntax. I use netlify.toml when I also need headers, build settings, and other config in the same place.
Common patterns
Rename a page
/blog-old /blog 301
Use 301 (permanent) when the old URL should never come back. This tells search engines to update their index.
Redirect an entire directory
/docs/* /documentation/:splat 301
The * matches everything after /docs/, and :splat passes it through. So:
/docs/getting-started→/documentation/getting-started/docs/api/auth→/documentation/api/auth
I've used this pattern for every site migration I've done. It's incredibly useful.
Short URLs to external sites
/github https://github.com/your-org/your-repo 302
I have a few of these on every project. Way easier to remember than a full GitHub URL.
Status codes matter
301 (Permanent) — "This URL has moved forever. Update your bookmarks." Use this for renamed pages, domain migrations, anything that's not coming back.
302 (Temporary) — "This URL is redirected for now, but might come back." Use this for seasonal pages, A/B tests, or links that point to different places depending on context.
For SEO, the distinction matters. 301s pass link equity to the new URL. 302s don't (in theory — Google is smarter about this now, but 301 is still safer for permanent moves).
SPA rewrites
If you're building a single-page app with React, Vue, or similar — your app handles routing client-side, but Netlify doesn't know that. If someone navigates directly to /dashboard, Netlify looks for a dashboard/index.html file, doesn't find one, and returns a 404.
Fix it with a rewrite:
/* /index.html 200
This serves index.html for all routes while keeping the URL intact. The 200 status code is what makes it a rewrite instead of a redirect.
Important: put this rule at the bottom of your _redirects file. It's a catch-all, and it'll swallow more specific rules if it comes first.
Rule ordering
Redirects are processed top to bottom. More specific rules need to come first:
/blog/rss /feed.xml 301
/blog/* /posts/:splat 301
If you reversed these, /blog/rss would match the wildcard rule and never reach the specific one. When redirects aren't working, ordering is the first thing I check.
Country-based redirects
Netlify can redirect based on the visitor's country (evaluated at the edge, so it's fast):
[[redirects]]
from = "/"
to = "/fr"
status = 302
conditions = { Country = ["fr"] }
French visitors get sent to /fr, everyone else sees the default page. I've used this for localized landing pages — works really well.
Testing locally
The Netlify CLI runs your site locally with the same routing logic:
netlify dev
This processes redirects and rewrites just like production would. It's the fastest way to catch mistakes before deploying a broken redirect.
Things that bite people
_redirects in the wrong folder. It needs to be in the final build output, not the project root. If your framework builds to dist/, the file needs to end up at dist/_redirects.
Using 301 when you meant 200. This breaks SPA routing. If your React app is showing 301 redirects instead of rendering, you used the wrong status code.
Overlapping wildcards. Always put specific rules before catch-alls. The /* rewrite should be the last line.
Trailing slashes. Netlify's pretty forgiving about this, but inconsistency can cause subtle issues. Pick a convention (trailing slash or no trailing slash) and stick with it.
When to use redirects vs. fixing links
If you control the source code, update the actual links instead of adding a redirect. Redirects are best for:
- URLs you don't control (external links, search engine results)
- Migrations from other platforms
- Backward compatibility with old URL structures
- Short/branded URLs
Don't use redirects as a crutch for messy internal navigation. Fix the links, then add redirects for the external references you can't control.

Developer Advocate at RevenueCat and creator of Netli.fyi. Building on Netlify since 2019. Writes from hands-on experience deploying dozens of production sites.
Manage Netlify on the go
Download Netli.fyi and monitor your sites, check deploys, and manage your projects from anywhere.


