Dynamic and Nested Routes
Static folders work well for predefined pages, but dynamic applications (such as e-commerce platforms or blog sites) require routing paths based on variable identifiers. Next.js supports this with Dynamic Routes.
1. Creating Dynamic Routes
To create a dynamic route segment, wrap the folder name in square brackets. For example, [id] or [slug].
src/app/
└── blog/
└── [slug]/
└── page.tsx # Dynamic blog route (/blog/post-1, /blog/hello-world)Next.js will pass the dynamic segment value to the page component as a prop.
2. Accessing Route Parameters (params)
In Next.js 15, route parameters are provided as a Promise. You must resolve the promise using async-await before reading its properties:
// src/app/blog/[slug]/page.tsx
interface PageProps {
params: Promise<{ slug: string }>;
}
export default async function BlogPostPage({ params }: PageProps) {
const resolvedParams = await params;
const slug = resolvedParams.slug;
return (
<article className="p-8">
<h1>Post Identifier: {slug}</h1>
<p>Reading content from database...</p>
</article>
);
}3. Catch-All Routing Segments
If you want your route to catch all subsequent path segments (for example, creating a documentation site with arbitrary folder nesting levels), extend the dynamic bracket syntax by adding three dots prefix inside the brackets: [...slug].
src/app/
└── docs/
└── [...slug]/
└── page.tsx # Catches /docs/setup, /docs/setup/install/linux, etc.If a user visits /docs/setup/install, the resolved slug param will be an array of strings: ["setup", "install"].
interface DocsProps {
params: Promise<{ slug: string[] }>;
}
export default async function DocsPage({ params }: DocsProps) {
const resolvedParams = await params;
const pathSegments = resolvedParams.slug; // e.g., ["setup", "install"]
return (
<div>
<p>Path: {pathSegments.join(" / ")}</p>
</div>
);
}4. Optional Catch-All Routing
By default, catch-all routes throw a 404 error if visited at the root folder path (such as /docs without any suffix segments).
To make the root path optional, wrap the folder name in double square brackets: [[...slug]]. This folder configuration will match both /docs (empty array) and /docs/any/nested/path.