Dynamic Routes
Bracket-named files, getStaticPaths, and building pages for data-driven URLs like blog posts.
阅读需 2 分钟
Most sites have pages that repeat the same layout for many pieces of data — a blog post per article, a product page per SKU. Writing one .astro file per item clearly doesn't scale, so Astro lets a single file, named with square brackets, generate a whole family of routes.
A bracketed filename becomes a URL parameter
src/pages/blog/[slug].astroThis single file can produce /blog/first-post, /blog/second-post, and any other /blog/<anything> — slug is a placeholder for whatever value fills that segment.
getStaticPaths: telling Astro which pages to build
In Astro's default static output mode, the framework needs to know, ahead of time, every value slug can take, so it can pre-render each one as its own HTML file at build time. That's the job of getStaticPaths, an exported function the file must define:
---
// src/pages/blog/[slug].astro
export async function getStaticPaths() {
const posts = [
{ slug: "first-post", title: "My First Post", body: "Hello, world!" },
{ slug: "second-post", title: "Getting the Hang of It", body: "Still going." },
];
return posts.map((post) => ({
params: { slug: post.slug },
props: { post },
}));
}
const { post } = Astro.props;
---
<html lang="en">
<head>
<title>{post.title}</title>
</head>
<body>
<h1>{post.title}</h1>
<p>{post.body}</p>
</body>
</html>getStaticPaths returns an array of objects, one per page to generate. params supplies the value that fills [slug] in the URL, and props hands that page whatever data it needs to render — here, the full post object, so the template doesn't have to re-fetch or re-look-up anything. Astro calls this function once at build time and produces one static HTML file per returned entry.
Where the data comes from
In this example the posts array is hardcoded, but in a real project getStaticPaths typically reads from a content collection (covered in a later lesson) or fetches from a CMS/API — the function can be async and await a data source before returning its list of pages.
Multiple dynamic segments
Bracket syntax composes for nested dynamic values:
src/pages/blog/[category]/[slug].astro---
export async function getStaticPaths() {
return [
{ params: { category: "tutorials", slug: "first-post" } },
{ params: { category: "news", slug: "site-update" } },
];
}
const { category, slug } = Astro.params;
---
<p>Category: {category}, Post: {slug}</p>Astro.params gives you the actual values Astro matched for the current page, read the same way regardless of how many bracketed segments the path has.
Static vs. server mode
Everything above assumes Astro's default static output, where getStaticPaths runs at build time and every route becomes a real HTML file. In server output mode (covered in a later lesson), [slug].astro instead runs per-request, reading Astro.params directly with no getStaticPaths needed — useful when the set of valid slugs is too large, or too frequently changing, to pre-build.