Skip to main content
Practice Problems

Dynamic routes and dynamic segments in Next.js

What are Dynamic Routes?

Dynamic routes allow you to create pages that match variable URL segments. Instead of creating a file for every possible path, you use bracket notation to define dynamic parameters.


Basic Dynamic Segments

app/ blog/ [slug]/ page.tsx → /blog/hello-world, /blog/my-post users/ [id]/ page.tsx → /users/1, /users/abc
tsx
// app/blog/[slug]/page.tsx export default async function BlogPost({ params, }: { params: Promise<{ slug: string }>; }) { const { slug } = await params; const post = await getPost(slug); return ( <article> <h1>{post.title}</h1> <div>{post.content}</div> </article> ); }

Catch-All Segments

Match multiple path segments with [...param]:

app/ docs/ [...slug]/ page.tsx → /docs/a, /docs/a/b, /docs/a/b/c
tsx
// app/docs/[...slug]/page.tsx export default async function Docs({ params, }: { params: Promise<{ slug: string[] }>; }) { const { slug } = await params; // /docs/react/hooks → slug = ["react", "hooks"] return <div>Path: {slug.join("/")}</div>; }

Optional Catch-All Segments

Match the path with or without segments using [[...param]]:

app/ shop/ [[...categories]]/ page.tsx → /shop, /shop/clothes, /shop/clothes/shirts
tsx
// app/shop/[[...categories]]/page.tsx export default async function Shop({ params, }: { params: Promise<{ categories?: string[] }>; }) { const { categories } = await params; // /shop → categories = undefined // /shop/clothes → categories = ["clothes"] // /shop/clothes/men → categories = ["clothes", "men"] return <ProductGrid categories={categories} />; }

generateStaticParams

Pre-render dynamic routes at build time:

tsx
// app/blog/[slug]/page.tsx export async function generateStaticParams() { const posts = await getAllPosts(); return posts.map((post) => ({ slug: post.slug, })); } // Generates: /blog/post-1, /blog/post-2, etc. at build time

Multiple Dynamic Segments

app/ [locale]/ blog/ [slug]/ page.tsx → /en/blog/hello, /ua/blog/hello
tsx
// app/[locale]/blog/[slug]/page.tsx export default async function BlogPost({ params, }: { params: Promise<{ locale: string; slug: string }>; }) { const { locale, slug } = await params; const post = await getPost(slug, locale); return <article>{post.title}</article>; }

Summary

PatternExampleMatches
[slug]/blog/[slug]/blog/hello (one segment)
[...slug]/docs/[...slug]/docs/a/b/c (one or more)
[[...slug]]/shop/[[...slug]]/shop, /shop/a/b (zero or more)

Important:

Dynamic routes are the foundation of Next.js routing. Use [param] for single segments, [...param] for catch-all, and [[...param]] for optional catch-all. Combine with generateStaticParams for static generation of dynamic pages.

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.

Finished reading?
Practice Problems