A guide to routing in Next.js (App Router) covering Catch-All Segments, Dynamic Routes, Nested Routes, and more.
Click to zoomIn Next.js (when using the App Router), the `src/app` directory serves as the foundation for your application's structure. Key files inside this directory include:
Suppose you want to have a homepage accessible at:
To achieve this, ensure that a `page.tsx` file exists inside the `src/app` directory. By default, this file is created when you initialize a Next.js project.
Now, let's say you want to create additional pages with different URLs.
To create a page accessible at:
Follow these steps:
export default function About() {
return <h1>Hello from About</h1>;
}
If you want a page accessible at:
Follow the same steps as above:
export default function Ramx() {
return <h1>Hello from Ramx</h1>;
}
After adding these pages, your `src/app` directory will look like this:
src/app/
layout.tsx - Defines layout structure
page.tsx - Homepage
about/
page.tsx - About Page
ramx/
page.tsx - Ramx Page
Suppose you want to handle the following routes:
This will create the route:
Brute force method (Good for small projects, but not recommended for scalability):
Manually create separate folders:
src/app/blog/first/page.tsx
src/app/blog/second/page.tsx
Each file should contain:
export default function FirstBlog() {
return <h1>First Blog Post</h1>;
}
export default function SecondBlog() {
return <h1>Second Blog Post</h1>;
}
Click to zoom
Suppose you want to create a product listing page where:
Each product also has a details page, such as `/products/1`.
Manually create:
src/app/products/product-1/page.tsx
src/app/products/product-2/page.tsx
src/app/products/product-3/page.tsx
Instead of manually creating pages for each product, use dynamic routing.
Your folder structure should look like:
src/app/products/
page.tsx # Product listing page
[productId]/
page.tsx # Dynamic product page
export default function ProductPage({
params,
}: {
params: { productId: string };
}) {
return <h1>Product ID: {params.productId}</h1>;
}
Now, if you visit `http://localhost:3000/products/100`, the `params.productId` will be `100`, and it will render dynamically.
Let's say you need URLs like:
src/app/categories/
[categoryId]/
page.tsx # Category page
[subCategoryId]/
page.tsx # Sub-category page
export default function CategoryPage({
params,
}: {
params: { categoryId: string };
}) {
return <h1>Category: {params.categoryId}</h1>;
}
export default function SubCategoryPage({
params,
}: {
params: { categoryId: string; subCategoryId: string };
}) {
return (
<h1>
{params.subCategoryId} in {params.categoryId}
</h1>
);
}
If you need to handle any level of nested paths, use a catch-all segment.
src/app/docs/
[...slug]/
page.tsx
export default function DocsPage({ params }: { params: { slug?: string[] } }) {
return (
<div>
<h1>Docs Page</h1>
<p>Path: {params.slug ? params.slug.join(" / ") : "Home"}</p>
</div>
);
}
"You have a right to perform your prescribed duty, but you are not entitled to the fruits of actions."
Design by SahilCodex
© 2026. Build with Hands.