Routing in Next.js (App Router) - A Complete Guide (2025)

A guide to routing in Next.js (App Router) covering Catch-All Segments, Dynamic Routes, Nested Routes, and more.

Routing in Next.js (App Router) - A Complete Guide (2025)Click to zoom
frontenddevelopmentnextjs

Understanding the `src/app` Directory

In 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:

  • `layout.tsx` – Defines the layout for your application, allowing you to persist UI elements across different pages.
  • `page.tsx` – Represents the content of a particular route.

Scenario 1: Creating a Homepage

Suppose you want to have a homepage accessible at:

`http://localhost:3000/`

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.

Scenario 2: Creating Additional Pages

Now, let's say you want to create additional pages with different URLs.

Creating an About Page

To create a page accessible at:

`http://localhost:3000/about`

Follow these steps:

  1. Inside the `src/app` directory, create a new folder named `about`.
  2. Inside `about`, create a `page.tsx` file.
  3. Add the following code:
export default function About() {
  return <h1>Hello from About</h1>;
}

Creating a Custom Page (e.g., Ramx Page)

If you want a page accessible at:

`http://localhost:3000/ramx`

Follow the same steps as above:

  1. Inside `src/app`, create a folder named `ramx`.
  2. Inside `ramx`, create a `page.tsx` file.
  3. Add the following code:
export default function Ramx() {
  return <h1>Hello from Ramx</h1>;
}

Folder Structure for the Pages

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

Nested Routes

Scenario 3: Creating Blog Pages

Suppose you want to handle the following routes:

Steps:

  1. First, create a `blog` folder inside `src/app`.
  2. Inside `blog`, create a `page.tsx` file.

This will create the route:

`http://localhost:3000/blog`

Handling `/blog/first` and `/blog/second`

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>;
}

routesClick to zoom


Dynamic Routing

Scenario 4: Creating a Product Listing Page

Suppose you want to create a product listing page where:

  • `/products` lists all products.
  • Individual product pages exist at `/products/product-1`, `/products/product-2`, etc.

Each product also has a details page, such as `/products/1`.

Brute Force Method (Not Scalable)

Manually create:

src/app/products/product-1/page.tsx
src/app/products/product-2/page.tsx
src/app/products/product-3/page.tsx

Using Dynamic Routing (Recommended Method)

Instead of manually creating pages for each product, use dynamic routing.

Steps:

  1. Create a folder named `[productId]` inside `src/app/products/`.
  2. Inside `[productId]`, create a `page.tsx` file.

Your folder structure should look like:

src/app/products/
   page.tsx   # Product listing page
   [productId]/
      page.tsx  # Dynamic product page

Code for 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.


Nested Dynamic Routes

Scenario 5: Category & Product Pages

Let's say you need URLs like:

Steps to Implement:

  1. Create a `categories` folder inside `src/app`.
  2. Inside `categories`, create a dynamic `[categoryId]` folder.
  3. Inside `[categoryId]`, create a dynamic `[subCategoryId]` folder.
  4. Add `page.tsx` inside both folders.

Folder Structure:

src/app/categories/
   [categoryId]/
      page.tsx  # Category page
      [subCategoryId]/
         page.tsx  # Sub-category page

Code for Category Page:

export default function CategoryPage({
  params,
}: {
  params: { categoryId: string };
}) {
  return <h1>Category: {params.categoryId}</h1>;
}

Code for Sub-Category Page:

export default function SubCategoryPage({
  params,
}: {
  params: { categoryId: string; subCategoryId: string };
}) {
  return (
    <h1>
      {params.subCategoryId} in {params.categoryId}
    </h1>
  );
}

Catch-All Segments

Scenario 6: Handling Unknown Nested Routes

If you need to handle any level of nested paths, use a catch-all segment.

Example URLs:

How to Implement:

  1. Inside `src/app`, create a `docs` folder.
  2. Inside `docs`, create a `[...slug]` folder (the three dots indicate "catch-all").
  3. Inside `[...slug]`, create `page.tsx`.

Folder Structure:

src/app/docs/
   [...slug]/
      page.tsx

Code for Catch-All Route:

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."
Bhagavad Gita

Design by SahilCodex
© 2026. Build with Hands.