getStaticPaths

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.

4 min read Level 2/5 #astro#getStaticPaths#ssg
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 →