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]'
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.
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.
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:
- Folder Structure: Shows how routes are defined based on folder names.
- Routing Flow: Illustrates how requests are mapped to specific page files.
- Layouts: Displays the hierarchy and how pages are nested within layouts.