Next.js App Router - How Routing Works?

The App Router in Next.js 14 brings a component-driven approach to routing, enabling developers to define pages, layouts, and other route features through folder structure. Below, we dive into the key aspects of the App Router, with TypeScript code examples for clarity.

1. Defining Routes

Routes in the App Router are created through the folder structure within the app directory. Each folder and file inside app represents a route segment. This folder-based routing system replaces the traditional pages folder and provides more flexibility and control.

Basic Structure Example:

app/ ├── layout.tsx // Root layout for the entire app ├── page.tsx // Default route: '/' ├── about/ │ └── page.tsx // '/about' route └── products/ └── [id]/ └── page.tsx // Dynamic route: '/products/[id]'
Pasted%20image%2020240924173740

2. Pages

Pages are components that render content for a specific route and are defined in page.tsx files. A page.tsx file directly inside a folder renders the page for that folder's route.

Pasted%20image%2020240924173814

Example: Basic Page Component

// app/page.tsx
export default function HomePage() {
  return <h1>Welcome to the Home Page</h1>;
}

3. Layout and Templates

Layouts are used to define shared UI components (like headers, footers, and navigation bars) that wrap around page content. They help maintain a consistent structure across different pages. Templates are similar but can be nested and reused within the routing structure to provide a nested layout system.

Pasted%20image%2020240924173837

Example: Dashboard Layout

// app/layout.tsx
export default function DashboardLayout({
  children, // will be a page or nested layout
}: {
  children: React.ReactNode
}) {
  return (
    <section>
      {/* Include shared UI here e.g. a header or sidebar */}
      <nav></nav>
 
      {children}
    </section>
  )
}

Example: Root Layouts

// app/layout.tsx
export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html lang="en">
      <body>
        {/* Layout UI */}
        <main>{children}</main>
      </body>
    </html>
  )
}

4. Linking and Navigating

For navigation, Next.js provides the Link component from next/link. This component enables client-side navigation between routes without a full page reload, offering a faster and smoother user experience.

Example: Using Link for Navigation

// app/page.tsx
import Link from 'next/link';

export default function HomePage() {
  return (
    <div>
      <h1>Home Page</h1>
      <Link href="/about">Go to About Page</Link>
    </div>
  );
}

5. Error Handling

Next.js 14 allows defining error pages using the error.tsx file. Errors thrown within a route's components will automatically render this error page, allowing you to handle issues gracefully.

Example: Basic Error Handling

// app/error.tsx
'use client'; // Required to run the component on the client-side

export default function ErrorPage({ error, reset }: { error: Error; reset: () => void }) {
  return (
    <div>
      <h1>Something went wrong!</h1>
      <p>{error.message}</p>
      <button onClick={() => reset()}>Try Again</button>
    </div>
  );
}

6. Redirecting

Redirection in the App Router can be done using the redirect function from next/navigation. This function allows you to programmatically redirect users to a different route.

Example: Redirect on Render

// app/page.tsx
import { redirect } from 'next/navigation';

export default function HomePage() {
  redirect('/about'); // Redirects users to the '/about' page automatically
  return null; // This component won't render as the redirect happens first
}

7. Route Groups

Route Groups allow organizing routes without affecting the URL path by wrapping route folders in a group that starts with a parenthesis. This technique is useful for sharing layouts between pages without altering the routing path.

Example: Using Route Groups

app/ ├── (marketing)/ │ ├── about/ │ │ └── page.tsx // '/about' │ └── contact/ │ └── page.tsx // '/contact' └── (admin)/ ├── dashboard/ │ └── page.tsx // '/dashboard' └── settings/ └── page.tsx // '/settings'

8. Dynamic Routes

Dynamic routes are defined by wrapping a route segment in square brackets ([param]). This feature allows capturing dynamic URL parameters, like product IDs, user profiles, etc.

Example: Dynamic Route

// app/products/[id]/page.tsx
export default function ProductPage({ params }: { params: { id: string } }) {
  return <h1>Product ID: {params.id}</h1>;
}

Diagram Explanation

To visualize these concepts:

  1. Folder Structure: Shows how routes are defined based on folder names.
  2. Routing Flow: Illustrates how requests are mapped to specific page files.
  3. Layouts: Displays the hierarchy and how pages are nested within layouts.
Clap here if you liked the blog