Domains, redirects, and headers
Configure static redirects and headers
Use Pages routing files for deliberate URL changes and response headers without adding a Function to every request.
8 minute lesson
Pages reads two plain-text files from your build output: _redirects and _headers. They handle many routing and header jobs during deployment, with no code running per request.
That location detail matters. The files must end up in the deployed output directory. A _redirects sitting in your repository root while the build deploys dist/ is silently ignored — put it in your static assets folder so the build copies it, and check the deployed site, not your source tree.
Redirects
One rule per line: source, destination, status.
/old-pricing /pricing 301
/blog/* /articles/:splat 301
The * captures the rest of the path and :splat reinserts it, so /blog/hello becomes /articles/hello.
Order and shape matter. Keep exact redirects before broad wildcard rules, because Pages applies static rules first and a too-early splat can shadow later rules. There are also hard limits — currently 2,000 static rules but only 100 dynamic (*) rules per file — so a site that generates thousands of wildcard rules will find some of them silently inert.
A redirect changes navigation; it does not preserve a request body unless its status and client behavior support that need. Redirecting a form POST with a 301 typically turns it into a GET and drops the payload.
Headers
_headers attaches response headers to paths:
/assets/*
Cache-Control: public, max-age=31536000, immutable
/*
X-Content-Type-Options: nosniff
Referrer-Policy: strict-origin-when-cross-origin
Use headers for cache policy and browser security where static configuration is enough. Long-lived caching belongs on fingerprinted assets whose names change on every build. Do not apply long-lived caching to HTML until you understand release freshness — an HTML page cached for a year keeps referencing asset names from a year ago.
Verify the deployed result
Test the deployed result, both preview and production:
curl -I https://my-site.pages.dev/old-pricing
# HTTP/2 301
# location: /pricing
curl -sI https://my-site.pages.dev/ | grep -i x-content-type-options
# x-content-type-options: nosniff
Now add one permanent old-path redirect and one security header to a practice project, then test both on the preview deployment before the production one.
Lesson completed