Dynamic Routes
Capture URL parameters with bracket folders. Build product pages, blog posts and user profiles without listing them all.
Static routes only get you so far. For a blog you don't want to write a page for every post — you want one template that reads the slug from the URL. The App Router does this with bracket-named folders.
A single dynamic segment
app/blog/[slug]/page.js → /blog/hello, /blog/world, …Inside the page, you receive the captured value through the params prop. In Next.js 16 params is a Promise that you must await:
// app/blog/[slug]/page.js
export default async function PostPage({ params }) {
const { slug } = await params;
const post = await getPost(slug);
return <article>{post.body}</article>;
}Catch-all and optional catch-all
- **
[...path]** — catches one or more segments.params.pathis an array like['a', 'b']. - **
[[...path]]** — same, but also matches the base URL with no path at all.
app/docs/[...slug]/page.js → /docs/a, /docs/a/b/c (matches anything below /docs)
app/shop/[[...filters]]/page.js → /shop AND /shop/red/largePre-generating dynamic pages
If you know the set of values ahead of time, you can pre-render them at build time using generateStaticParams:
// app/blog/[slug]/page.js
export async function generateStaticParams() {
const posts = await getAllPosts();
return posts.map((p) => ({ slug: p.slug }));
}
export default async function PostPage({ params }) {
const { slug } = await params;
// ...
}Pages whose params come from generateStaticParams are built as static HTML — no server work at request time. Anything not in the list still renders on demand by default.
Reading search params
Query strings like ?q=react&page=2 arrive in a separate prop called searchParams, also a Promise:
export default async function SearchPage({ searchParams }) {
const { q = "" } = await searchParams;
const results = await search(q);
return <Results items={results} />;
}searchParams opts the page out of static rendering, since they change per request. That's usually what you want.Try it
Wire up a dynamic product page that reads the `id` from the URL and passes it to `getProduct`.
Need a hint?
The folder name in brackets matches the prop key, e.g. [id] → params.id.
Quiz
Pick the best answer. You only get one shot per question.
1. Which file matches both /docs and /docs/getting-started?
2. In Next.js 16, what is the type of `params` inside a page?
3. What does `generateStaticParams` do?