Skip to content

Add redirects and rewrites

Put a file named _redirects at the root of your publish directory (the folder your build outputs, such as dist or public). deploybase reads it after each build and applies its rules at the edge. The syntax is Netlify’s, so a file you already have works without changes, apart from the unsupported features below.

# Moved pages
/old-pricing /pricing 301
/blog/* /articles/:splat 301
/docs/:version/* /documentation/:splat 302
# Serve one file for several paths
/app/* /app/index.html 200
# A custom 404 for one section
/shop/* /shop/not-found.html 404
# One host onto another
https://www.example.com/* https://example.com/:splat 301!

Rules apply to deployments built since deploybase started applying _redirects (October 2026). A deployment built before then ignores its _redirects file until you redeploy it.

One rule per line: FROM TO [STATUS]. Separate the fields with spaces or tabs. A line starting with # is a comment, and blank lines are ignored.

  • FROM is the path a visitor requests. It starts with /, or with https:// for a rule on one hostname.
  • TO is where the visitor goes: a path on your site, or a full https:// URL for a redirect.
  • STATUS is optional and defaults to 301.
Status What happens
301 Permanent redirect. Browsers and search engines remember it
302 Temporary redirect
308 Permanent redirect that keeps the request method
200 Rewrite: the visitor stays on FROM and gets the file at TO
404 The visitor gets the file at TO with a 404 status

A 200 or 404 rule only takes effect when TO is a file in the deployment. deploybase resolves it the way it resolves any request, so /app/ finds /app/index.html and /about finds about.html. When the file does not exist, the rule is passed over and the next one is checked.

Matching is case-sensitive, and a trailing slash does not matter: /pricing and /pricing/ match the same rule.

A * at the end of FROM matches the rest of the path. Use :splat in TO to put that part back:

/blog/* /articles/:splat 301

/blog/2026/launch redirects to /articles/2026/launch. /blog/* also matches /blog itself. Only one * is allowed, and only as the last character.

A path segment written as :name matches any single segment, and :name in TO inserts it:

/team/:member /people/:member 301

/team/ada redirects to /people/ada. A placeholder must be a whole segment, made of letters, digits and underscores. A :name in TO that does not appear in FROM is left as literal text.

By default a rule only applies when no file matches the request, so a rule for /about does nothing while about.html is deployed. Add ! after the status to apply the rule even when the file exists:

/about /company 301!

Start FROM with a full URL to make a rule apply on one hostname only. The common case is sending www to the root domain, or the other way round:

https://www.example.com/* https://example.com/:splat 301!

The hostname must be attached to the project: its sites.deploybase.eu address, or one of its custom domains, including the www name that comes with a root domain. A rule for any other hostname is skipped with a warning. The scheme is ignored when matching, so http:// and https:// in FROM mean the same thing.

If the project has a primary address, its other addresses already redirect there before any rule is checked. You only need a hostname rule for a redirect the primary address does not cover.

The visitor’s query string is kept on a redirect. /old-pricing?plan=team with the rule /old-pricing /pricing 301 lands on /pricing?plan=team. If TO already has a query string, the visitor’s is appended after it.

For each request, the first match wins:

  1. The redirect to your project’s primary address, if one is set.
  2. Rules with !, in file order.
  3. Files in the deployment, including clean URLs (/about serving about.html).
  4. Rules without !, in file order.
  5. Your framework’s server-side rendering, the SPA fallback or the 404 page, as described in serving paths that have no file.

Put specific rules above general ones. A /* rule near the top of the file catches everything below it.

A line deploybase cannot use is skipped, and the rest of the file still applies. Each skipped line is reported in the build log with its line number and the reason:

⚠️ _redirects line 7 skipped: query and condition matching are not supported

Warnings do not fail the build, so check the log after changing the file.

  • Up to 1,000 rules per file. A file with more is not applied at all, and the build log says so.
  • The file can be up to 1 MB. A bigger file is not applied.
  • FROM and TO can each be up to 2,000 characters. Characters outside ASCII in TO are percent-encoded for you.
  • Query and condition matching. Rules such as /store id=:id /products/:id or / /nl 302 Country=nl are skipped. So are Language, Role and any other condition.
  • Proxying to another site. A 200 or 404 rule must point at a file in your deployment. A full URL there is skipped with “proxying to another origin is not supported”. Use a 301 or 302 to send visitors to another site.
  • Placeholders in a destination hostname. https://:sub.example.com/ is skipped, so a rule cannot be turned into an open redirect.
  • Redirects in netlify.toml. deploybase does not read [[redirects]] blocks. Move them into _redirects.
  • Paths outside your deployment. A rewrite cannot reach .. or another project’s files.

Live b001be8d built