Dynamic Routes

`[slug].astro` Captures Variable URL Segments

Dynamic Routes

Brackets in a filename make it a dynamic route. `[slug].astro` matches `/anything`, `[...path].astro` matches any depth.

4 min read Level 2/5 #astro#routing#dynamic
What you'll learn
  • Write a `[slug]` route
  • Use a `[...catchall]` rest route
  • Recognize the static-vs-server difference

A filename in [brackets] captures part of the URL as a parameter.

A Single Param

src/pages/blog/[slug].astro

Matches /blog/anything. Inside the page, Astro.params.slug holds the captured value.

---
const { slug } = Astro.params;
---
<h1>Reading: {slug}</h1>

Multiple Params

src/pages/users/[userId]/posts/[postId].astro

Matches /users/42/posts/7. Both Astro.params.userId and Astro.params.postId are available.

Rest Routes — Match Anything

[...rest].astro captures the rest of the path:

src/pages/docs/[...path].astro

Matches /docs/, /docs/intro, /docs/advanced/effects/etc. Astro.params.path is the captured string (or undefined at /docs/).

Static vs Server Mode

For a static build (the default), Astro needs to know which slugs exist at build time. You provide them with getStaticPaths — the next lesson.

For server mode, the route matches any incoming URL at request time. We’ll cover that in the server chapter.

A Quick Example

---
// src/pages/users/[id].astro

export async function getStaticPaths() {
  return [
    { params: { id: "1" } },
    { params: { id: "2" } },
    { params: { id: "3" } },
  ];
}

const { id } = Astro.params;
---

<h1>User #{id}</h1>

This builds three pages: /users/1, /users/2, /users/3. Every other URL is a 404.

Up Next

getStaticPaths in depth — including passing extra data to the page.

getStaticPaths →