Two Ways — Config and Runtime
Redirects
Static redirects go in `astro.config.mjs`. Runtime redirects use `Astro.redirect` inside a page or endpoint.
What you'll learn
- Configure a static redirect
- Redirect at request time with `Astro.redirect`
Two flavors of redirect, depending on whether you know the destination at build time or at request time.
1. Config-Level Redirects
For static, known redirects, list them in astro.config.mjs:
import { defineConfig } from "astro/config";
export default defineConfig({
redirects: {
"/old-page": "/new-page",
"/blog/[slug]": "/posts/[slug]",
"/docs": { status: 302, destination: "/docs/intro" },
},
}); - A string → 301 (permanent)
- An object → custom status code (302 for temporary, etc.)
- Dynamic patterns work —
[slug]in the source matches in the destination
These work in static mode — Astro generates HTML that includes the
right meta-refresh, plus a _redirects file for hosts that
understand them (Netlify, Cloudflare).
2. Runtime Redirects
Inside a page’s frontmatter, return Astro.redirect:
---
// src/pages/dashboard.astro
const user = await getCurrentUser(Astro);
if (!user) {
return Astro.redirect("/login");
}
---
<h1>Welcome, {user.name}</h1> Requires server mode (or hybrid with this page non-prerendered).
The redirect is a real Response with a Location header.
You can pass a status:
---
return Astro.redirect("/login", 302); // default 302
--- In Endpoints
Endpoints (covered in chapter 6) return Response objects directly
— including redirects:
export async function GET() {
return Response.redirect("https://example.com/new", 301);
} Up Next
When nothing matches — the 404 page.
404 Page →