# Dynamic Routing and Catch-All Routes in Next.js

Dynamic routing in Next.js allows you to create flexible routes that adapt to user input. This feature is particularly useful for building dynamic applications like blogs, e-commerce sites, and user-specific dashboards. Additionally, Next.js provides robust support for handling non-existent routes through custom 404 pages and catch-all routes.

---

## What is Dynamic Routing?

Dynamic routing enables you to define routes where part of the URL can change dynamically. For example:

* `/product/[id]` can match URLs like `/product/1`, `/product/2` or `/product/special-item`.
    

---

## Difference Between `next/navigation` and `next/router`

Both `next/navigation` and `next/router` offer routing utilities, but they cater to different environments within Next.js.

### `next/navigation`

* **Scope**: Specifically designed for the App Router (introduced in Next.js 13).
    
* **Features**:
    
    * `useParams`: Access dynamic route parameters.
        
    * `useSearchParams`: Access query parameters.
        
    * `useRouter`: Provides navigation methods like `push`, `replace`, and `back`.
        
    * `notFound`: Programmatically trigger 404 pages.
        
    * `redirect`: Redirect users to a specific URL.
        

> **Recommended Use**: When using the App Router for building routes in the `src/app` directory.

### `next/router`

* **Scope**: Designed for the Pages Router (traditional routing system in Next.js).
    
* **Features**:
    
    * `useRouter`: Access the router object for navigation and dynamic route handling.
        
    * `query`: Access route parameters and query strings.
        
    * `prefetch`: Prefetch pages for better performance.
        
* **Recommended Use**: When building applications in the `src/pages` directory.
    

---

## Creating Dynamic Routes

### Step 1: Define a Dynamic Route File

To create a dynamic route, use square brackets (`[ ]`) in your file or folder name within the `pages` or `app` directory. For example:

```plaintext
src/app/products/[id]/page.tsx
```

### Step 2: Access the Dynamic Parameter

Inside your dynamic route, you can access the parameter using `params` (in the App Router) or `query` (in the Pages Router).

#### App Router Example:

```typescript
interface ProductPageProps {
  params: { id: string };
}

export default function ProductPage({ params }: ProductPageProps) {
  return <h1>Product ID: {params.id}</h1>;
}
```

#### Pages Router Example:

```typescript
import { useRouter } from 'next/router';

export default function ProductPage() {
  const router = useRouter();
  const { id } = router.query;

  return <h1>Product ID: {id}</h1>;
}
```

Inside your dynamic route, you can access the parameter using the `params` object provided by Next.js.

#### Example Using App Router:

```typescript
import { notFound } from 'next/navigation';

interface ProductPageProps {
  params: { id: string };
}

export default function ProductPage({ params }: ProductPageProps) {
  if (!params.id) {
    notFound();
  }

  return <h1>Product ID: {params.id}</h1>;
}
```

Alternatively, use the `useParams` hook from `next/navigation`:

```typescript
import { useParams } from 'next/navigation';

export default function ProductPage() {
  const params = useParams();

  if (!params.id) {
    return <h1>404 - Product Not Found</h1>;
  }

  return <h1>Product ID: {params.id}</h1>;
}
```

---

## Catch-All Routes

Catch-all routes match multiple URL segments and are defined using `[...param]` in the file or folder name.

### Example:

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

#### Handling Catch-All Parameters:

```typescript
interface DocsPageProps {
  params: { slug: string[] };
}

export default function DocsPage({ params }: DocsPageProps) {
  const slugPath = params.slug.join('/');

  return <h1>Viewing: {slugPath}</h1>;
}
```

This route will match paths like:

* `/docs`
    
* `/docs/getting-started`
    
* `/docs/tutorials/advanced`
    

---

## Optional Catch-All Routes

You can make a catch-all route optional by adding a question mark (`?`) in the file name:

This matches both `/docs` and any nested paths under `/docs`.

By adding a question mark (`?`) after the `...slug` part, you can make the catch-all segment optional, meaning the route will match even if there's no additional path segment after the base URL.

```plaintext
pages/docs/[...slug]?
This route will match:
- /docs
- /docs/post-title
- /docs/category/article-name
```

* **Usage:**
    
    This is particularly useful for creating fallback pages or handling situations where a user might access a URL with or without additional parameters.
    

---

## Handling 404 Errors

Next.js allows you to create a custom 404 page for non-existent routes.

### Step 1: Create a `404` Page

In the App Router:

```plaintext
src/app/not-found.tsx
```

In the Pages Router:

```plaintext
src/pages/404.tsx
```

### Step 2: Define the Custom 404 Page

```typescript
export default function NotFound() {
  return <h1>404 - Page Not Found</h1>;
}
```

With the App Router, you can also use the `notFound()` function to programmatically trigger a 404:

```typescript
import { notFound } from 'next/navigation';

export default function ProductPage({ params }: { params: { id: string } }) {
  if (!params.id) {
    notFound();
  }

  return <h1>Product ID: {params.id}</h1>;
}
```

---

## Practical Use Cases

1. **Blogs**:
    
    * `/blog/[slug]` for articles with unique slugs.
        
2. **E-Commerce**:
    
    * `/products/[id]` for individual product pages.
        
3. **Documentation**:
    
    * `/docs/[...slug]` for structured documentation paths.
        
4. **Custom 404 Pages**:
    
    * Enhance user experience with branded 404 pages.
        

---

## Conclusion

Dynamic and catch-all routes in Next.js provide a flexible and powerful way to build dynamic applications. By understanding how to create and use these routes effectively, you can handle a wide variety of use cases, from user-specific pages to structured documentation paths. Start exploring dynamic routing today to unlock the full potential of your Next.js applications!
