Pages and routing

Handle redirects and missing pages

Create an explicit redirect and a useful custom 404 instead of leaving broken navigation ambiguous.

URLs change. You rename a page, move a section into a folder, merge two posts. Every time, the old address is still out there, in search results, in bookmarks, in someone’s newsletter. You have two tools for this: redirects and a good 404 page.

Redirect a moved page

When content moved, keep the old file and make it point to the new one. In the component script:

---
return Astro.redirect('/new-path/', 301)
---

Astro.redirect() returns a response with a Location header. Returning it from the component script stops the render, so nothing below the fence matters.

Pick the status code from what happened. A page that moved for good uses 301 or 308. A temporary destination, like a maintenance page, uses a temporary status such as 302 or 307. Search engines treat these differently, so don’t pick at random.

For a handful of redirects, you can also list them in the redirects option of astro.config.mjs. Same idea, one place to look.

Static redirects depend on the host

In a static build there is no server to send a 301. Astro produces an HTML page that redirects the browser instead, unless your adapter or host translates the redirect into a real HTTP response.

So don’t trust local navigation to prove the status. After deploying, check the actual headers:

curl -I https://notes.flaviocopes.com/old-path/

You want to see the status line and a Location header pointing at the new URL.

Avoid redirect chains

Over the years, an old URL can end up pointing to a slightly newer URL, which points to the current one. Each hop is a round trip and a chance to break.

When you move a page again, update every old redirect to point straight to the final destination.

A useful 404 page

Create src/pages/404.astro. Most hosts serve it for any URL that doesn’t exist.

Make it useful. Say plainly that the page doesn’t exist, show the site navigation, and link to the sections people most likely wanted. A search box helps a lot here.

Be careful with one mistake: don’t turn every unknown URL into a 200 response that says “not found”. The HTTP status has to be 404. Browsers don’t care, but search engines and monitoring tools do.

Try this after your next deployment: request an old URL with curl -I, then request a made-up one. Check the status code, the Location header, and the final page you land on. That’s the whole check, and it takes a minute.

Lesson completed