Next.js 8: Nested Dynamic & Catch-All Routes
easy⏱ 5 mincoursenextjs
[...slug] catches multiple segments
A folder named [...slug] is a catch-all segment: it matches any number of path parts after it, not just one. app/docs/[...slug]/page.tsx matches /docs/a, /docs/a/b, /docs/a/b/c... and params.slug arrives as an array, e.g. ['a', 'b', 'c'].
// app/docs/[...slug]/page.tsx
export default function DocsPage({ params }: { params: { slug: string[] } }) {
return <p>Path: {params.slug.join(' / ')}</p>;
}
// /docs/guides/routing -> params.slug === ['guides', 'routing']
Double brackets make it optional
[...slug] requires at least one path part after /docs — visiting /docs itself would 404. Doubling the brackets, [[...slug]], makes the segment optional: it also matches /docs with zero parts, in which case params.slug is undefined. Use this when the base route (no extra path) should render too.
Build a breadcrumb from a slug array
Create a DocsPage component that receives params = { slug } (an array, possibly empty) and renders it as a breadcrumb (e.g. "docs / guides / routing"). Add buttons for a few preset paths of different lengths, including one that simulates the empty /docs optional case.