Redirects
Add _redirects at the publish root to redirect, rewrite, proxy, or return custom 404 responses. Stattic reads the file at deploy time and does not serve it.
/old /new 301
/blog/* /news/:splat 302
/app/* /index.html 200
/api/* https://api.example.com/:splat 200
/missing /404.html 404
Vite spaces can also define these rules in vite.config.ts with the Stattic Vite plugin. The plugin merges config rules with _redirects, applies them in the dev server, and writes the merged output file during build.
Line syntax
Each non-empty, non-comment line is a rule: source, optional query captures, destination, optional status, then optional conditions.
source [query=:capture ...] destination [status[!]] [Condition=value,... ...]
- Lines beginning with
#are comments. - Status defaults to
302. - Supported statuses are
200,301,302,303,307,308, and404. - Append
!to the status to force the rule, for example301!. - Each rule line can be up to 1,000 characters.
- A publish can include up to 2,100 redirect rules: 2,000 static rules and 100 dynamic rules.
Sources
A source must be an absolute path beginning with / or an absolute http/https URL. Exact sources match with or without a trailing slash.
/docs /guides 301
/docs/ /guides 301
https://www.example.com/docs /docs 301
https://:subdomain.example.com/* /sites/:subdomain/:splat 200
URL sources are host-specific. If a space has assigned hostnames, exact URL hosts must be assigned to the space. Host patterns may use * or placeholders.
Patterns
Use * for one splat capture named :splat. Use named placeholders such as :slug for one path segment. Reuse captures in the destination.
/blog/* /news/:splat 301
/posts/:year/:slug /blog/:year/:slug 301
/downloads/* https://cdn.example.com/files/:splat 302
/products/:id /shop/item/:id 308
- Only one wildcard is supported per pattern.
- Wildcards must appear at the end of a path segment.
- Wildcards and placeholders cannot be used in the same segment.
- Placeholder names must start with a letter and can be captured only once per pattern.
Static rules are exact path rules without a host constraint. Dynamic rules include any wildcard, placeholder, or host constraint.
Actions
| Status | Action | Destination |
|---|---|---|
301, 302, 303, 307, 308 | Redirect | Path or absolute URL. |
200 | Rewrite | Local path. |
200 | Proxy | Absolute http/https URL. |
404 | Custom not found | Local path. |
Query captures
Query captures sit between source and destination. Use name=:capture; query names must start with a letter and may include letters, numbers, underscores, or hyphens.
/search q=:q /results/:q 302
/api/search q=:q page=:page https://api.example.com/search?q=:q&page=:page 200
/legacy utm_campaign=:campaign /campaigns/:campaign 301
- The incoming query must contain exactly the listed query parameter names.
- Query order does not matter.
- Repeated query values are joined with commas before capture expansion.
- Redirects without query captures forward the original query when the destination has no query.
- Redirects with query captures do not forward unmatched original query values.
Conditions
Conditions come after the status. Stattic supports Country, Language, Cookie, and Agent. Values are comma-separated with no spaces. Country values must be two-letter country codes.
/pricing /pricing-eu 302 Country=NL,DE,FR
/ /nl 302 Language=nl
/preview /preview-authenticated 200 Cookie=stattic_preview
/promo /promo-us 302 Country=US Language=en
/ai /ai.txt 200 Agent=true
Netlify and Cloudflare migration aliases such as nf_country and cf_ipcountry are accepted with diagnostics. Role conditions are not supported.
Multiple conditions are combined with AND. Multiple comma-separated values inside one condition are combined with OR.
Use Agent=true when a URL should serve a plain-text version to AI agents while keeping the browser version for humans. Stattic treats requests as agent-like when they explicitly prefer text/plain or use a known agent user agent.
Runtime order
Rules run in file order. Browser redirects and external proxy rules run as soon as they match. Local rewrites and custom 404 rules are skipped when the original request resolves to a file, unless the rule status has !.
/app/* /app/index.html 200
/admin/* /admin/index.html 200!
The first rule preserves existing /app files. The second rule can shadow existing /admin files.
Invalid rules
Stattic rejects rules that are ambiguous, unsafe, or likely to loop.
# Missing destination
/old
# Unsupported status
/old /new 305
# Rewrite destination must be a path or absolute URL
/app/* index.html 200
# Custom 404 destination must be a path
/missing https://example.com/404 404
# This loops back to the same path
/docs /docs 301
Custom response headers use a separate Headers page. Proxy examples are covered in Proxy routes.