Tell Astro Which Dynamic URLs to Pre-Render
getStaticPaths
For a static build, dynamic routes need an explicit list of params. `getStaticPaths` returns them, plus optional `props` per page.
What you'll learn
- Export `getStaticPaths` from a page
- Return params and optional `props`
- Build pages from a content source
getStaticPaths is how a dynamic route page tells Astro which
URLs exist at build time. It exports an async function that
returns an array of { params, props } objects.
The Shape
---
// src/pages/blog/[slug].astro
export async function getStaticPaths() {
return [
{ params: { slug: "hello-world" } },
{ params: { slug: "second-post" } },
];
}
const { slug } = Astro.params;
---
<h1>{slug}</h1> Astro generates /blog/hello-world and /blog/second-post.
Pass Props to the Page
props lets you hand the page the data it needs, so it doesn’t
have to fetch again:
---
// src/pages/blog/[slug].astro
export async function getStaticPaths() {
const res = await fetch("https://api.example.com/posts");
const posts = await res.json();
return posts.map(post => ({
params: { slug: post.slug },
props: { post },
}));
}
const { post } = Astro.props;
---
<article>
<h1>{post.title}</h1>
<div set:html={post.html} />
</article> Now you fetch ONCE inside getStaticPaths, not once per page.
Building From Local Content
getStaticPaths shines when paired with content collections (later
chapter):
---
import { getCollection } from "astro:content";
export async function getStaticPaths() {
const posts = await getCollection("blog");
return posts.map(post => ({
params: { slug: post.id },
props: { post },
}));
}
const { post } = Astro.props;
const { Content } = await post.render();
---
<article>
<h1>{post.data.title}</h1>
<Content />
</article> Pagination
getStaticPaths accepts a paginate helper to split a large list
across pages:
---
export async function getStaticPaths({ paginate }) {
const posts = await getAllPosts();
return paginate(posts, { pageSize: 10 });
}
const { page } = Astro.props; // { data, currentPage, lastPage, ... }
---
<ul>
{page.data.map(p => <li>{p.title}</li>)}
</ul> Each page gets URLs like /blog/2, /blog/3, etc.
In Server Mode
For SSR pages (output: 'server' or prerender = false), you
don’t export getStaticPaths. The route matches at request
time. We cover this in the server chapter.
Up Next
Reading params and other URL info.
Route Params →