× press ESC to close

Netlify builds, deploys, and hosts your front end.

You can configure redirects and rewrite rules for your Netlify site by adding a _redirects file to the root of your site folder (note, if you’re running a build command, the _redirects file should end up in the folder you’re deploying. It’s not enough to have on in the root of your repository).

Basic redirects

Setting up basic redirects is straight forward:

# Redirects from what the browser requests to what we serve
/home              /
/blog/my-post.php  /blog/my-post
/news              /blog
/google            https://www.google.com

Just list the original path followed by the new path or URL.

Any # indicates a comment and everything following the pound sign will be ignored.

HTTP Status Codes

You can specify the HTTP status code for the rewrite. The default is 301 which will do a permanent redirect.

# Redirect with a 301
/home         /              301

# Redirect with a 302
/my-redirect  /              302

# Rewrite a path
/pass-through /index.html    200

# Show a custom 404 for this path
/ecommerce    /store-closed  404

When the status code is 301, 302 or 303 Netlify will redirect to the target url. With any other status code Netlify will render the target url with the specified status code.

This means that you can define rewrite rules as well as redirects by specifying 200 as the status code.

Custom 404

You can easily setup a custom 404 page for all paths that doesn’t resolve to a static file. This doesn’t require any redirect rules. Just add a 404.html page to your site and it’ll be picked up automatically.

Trailing Slash

Our CDN edge nodes do URL normalization before the redirect rules kick in. This happens to make sure we can guarantee the highest possible cache hit rate and the absolute best performance for your site.

When “Pretty URLs” is enabled under processing settings for your site, Netlify will enforce consistent URL patterns.

A link to /about.html will be rewritten to /about in your HTML files and Netlify will enforce a redirect from /about/ to /about

A link to /about/index.html will be rewritten to /about/ and Netlify will redirect from /about to /about/


You can use placeholders in the origin and target paths:

/news/:year/:month:/:date/:slug  /blog/:year/:month/:date/:slug

This would redirect a URL like /news/2004/02/12/my-story to /blog/2004/02/12/my-story


An asterisk indicates a splat that will match anything that follows:

You can use the splat in your rewrites or redirects like this:

/news/*  /blog/:splat

This would redirects paths like /news/2004/01/10/my-story to /blog/2004/01/10/my-story

Query Params

You can also use query parameters in your URL matches. The following match will redirect a URL like: /store?id=my-blog-post to /blog/my-blog-post with a 301 redirect.

/store id=:id  /blog/:id  301

Just add separate key/value pairs separated by space to match more than one query parameter.

History Pushstate and Single Page Apps

If you’re developing a single page app and want history pushstate to work so you get clean urls, you’ll want to enable the following rewrite rule:

/*    /index.html   200

This will effectively serve the index.html instead of giving a 404 no matter what URL the browser requests.


Just like you can rewrite paths like /* to /index.html, you can also set up rules to let parts of your site proxy to external services. Let’s say you need to communicate from a Single Page App with an API on https://api.example.com that doesn’t support CORS request. The following rule will let you use /api/ from your JavaScript client:

/api/*  https://api.example.com/:splat  200

Now all requests to /api/… will be proxied through to https://api.example.com straight from our CDN servers without an additional connection from the browser. If the API supports standard HTTP caching mechanisms like Etags or Last-Modified headers, the responses will even get cached by CDN nodes.

Note on shadowing

By default, you can’t shadow a URL that actually exists within the site when using a splat or dynamic path segment. This means that even if you’ve setup the following rewrite rule:

/*   /index.html   200

The path /partials/chat.html would still render the contents of that file, if that file actually exists. This tends to be the preferred behavior when setting up rewrite rules for single page apps, etc.

However, if you’re 100% sure that you’ll always want to redirect, even when the URL matches a static file, you can append an exclamation mark to the rule:

/app/*  /app/index.html  200!

This will rewrite everything within /app/* to /app/index.html even if a file matches the URL.

GeoIP and Language-based redirects

Netlify supports GeoIP and language-based redirects directly from our CDN nodes.

This is ideal for large multi-regional sites where you want to send people to the right location based on their location or browser language.

Both the language and the country can be specified in a cookie as well, so you can easily override the default behavior with JavaScript.

When you add these redirect rules, Netlify automatically creates alternate headers to enable the redirection in our CDN nodes. This removes the need for a roundtrip to our origin servers and ensures that normal pages, besides country or language based redirects, are cached on the CDN nodes.

The easiest way to understand these redirect capabilities is to look at some examples:

# Redirect users in China, Hongkong or Taiwan to /china
/  /china   302  Country=cn,hk,tw
# Redirect users in israel to /israel
/  /israel  302  Country=il

# Redirect users with chinese language preference from /china to /china/zn-ch
/china/*  /china/zn-ch/:splat  302  Language=zh

The system is smart enough to flatten chains of redirect. So in the above case, if a user from China with Chinese language preference visits /china, she’ll get redirected directly to /china/zn-ch in one step. Our cache server will cache this redirect for any other users that would match the same country and language rules.

You can find a list of country codes here: http://dev.maxmind.com/geoip/legacy/codes/iso3166/

And language codes here: http://www.metamodpro.com/browser-language-codes

For languages, note that en will match en-US and en-GB, zh will match zh-tw and zh-hk, etc.

Role based redirect rules

Role based redirects let you restrict access to certain paths of your application only to users with granted JWT tokens. This access control is implemented in our CDN, removing the need for a round trip to our origin servers. This feature is only available in Paid plans.

Before setting up these rules, make sure your JWT client secret is properly configured in our Visitor Access Control panel.

With this feature, you can set role conditions per redirect rule, like this one:

/admin/*	200!	Role=admin

The rule avobe, tells Netlify’s CDN to grant access to the /admin path and everything under it only to users which JWT tokens include the admin role in their app_metadata. Any other user that tries to access those URLs will be presented with a 404 page.

If you don’t want present a 404 page, you can set a fallback rule to redirect users to a specific page, like a login page. The next example adds a new rule to accomplish that:

/admin/*			200!	Role=admin
/admin/*	/login	401

The second rule in the example is what we call a fallback rule. It tell’s Netlify’s CDN that it must redirect every user that’s not in the admin role to a different page.

You can also grant several roles access to the same path by chaining them with commas:

/private/*		200!	Role=editor,admin

You can use this feature with authentication providers like Auth0, Stormpath or any other that can generate JWT tokes with roles metadata. To learn more about JWT tokens and app metadata, you can read more about them JWT specification.

Testing Redirects

You can test if the rules in your _redirects file are correct at Netlify’s Playground. Copy your rules there and click Test rules. The playground will list all the invalid rules in your file if there is any.


Netlify Playground is open source and freely distributable. You can read more about it in our blog.

Notice something is incorrect or outdated?

First off, great eye! We appreciate your discovery and want to ensure it gets addressed immediately. Please let us know here.

Want to get started quick?