Table of Contents
- Introduction
- What is Next.js Router?
- Pages Router in Next.js
- App Router in Next.js 13+
- Key Differences Between Pages Router and App Router
- When to Use Each Router
- Migrating from Pages Router to App Router
- Conclusion
1. Introduction
Next.js 13 introduced a new routing mechanism called the App Router, designed to give developers more flexibility and improve support for complex applications. Although the App Router provides numerous advantages, the older Pages Router is still widely used and fully supported. Understanding the differences between these two routers and their respective strengths is crucial for building modern React apps with Next.js.
In this module, we will explore both routing systems, highlight the key differences, and guide you on when to use each. We’ll also walk through the migration process for moving from the Pages Router to the App Router.
2. What is Next.js Router?
Next.js is built around a file-based routing system that links the file structure in the pages
or app
directory directly to application routes. Routing in Next.js can be broken down into:
- Pages Router (Traditional): This was the default routing system in Next.js before version 13, using the
pages
directory. - App Router (Introduced in Next.js 13): A new, more flexible routing system introduced in Next.js 13, leveraging the
app
directory for better layout handling, improved SSR, and more control over nested routes.
While the Pages Router is still available in Next.js 13, the App Router is now the recommended approach for new Next.js projects.
3. Pages Router in Next.js
The Pages Router follows a file-based routing pattern where every file within the pages
directory automatically corresponds to a route.
3.1 File-Based Routing
In the Pages Router, the file structure in the pages
directory directly correlates to the routes:
pages/index.js
corresponds to the/
route.pages/about.js
corresponds to the/about
route.pages/contact.js
corresponds to the/contact
route.- Nested routes, like
pages/blog/[slug].js
, map to dynamic routes/blog/1
,/blog/hello-world
, etc.
This simple file-to-route mapping system makes it easy to quickly set up and manage routes.
3.2 Dynamic Routes
Dynamic routing in Next.js is handled by using bracket notation in file names, enabling the creation of URLs that accept dynamic parameters. For instance:
pages/blog/[id].js
maps to/blog/1
,/blog/2
, etc., and you can access the dynamicid
usinguseRouter()
.
You can also use optional catch-all routes using [...param]
for more flexibility, like pages/posts/[...slug].js
, which can match /posts/first-post
or /posts/first-post/second-post
.
3.3 API Routes
Next.js supports API routes, allowing you to build server-side logic directly inside the Next.js app. These are defined in the pages/api
directory:
pages/api/hello.js
maps to/api/hello
, which can handle HTTP requests like GET, POST, etc.
API routes work well for building backend services like form submissions, handling user authentication, or managing simple CRUD operations.
3.4 Static Site Generation and Server-Side Rendering
In the Pages Router, Next.js provides getStaticProps (for Static Site Generation) and getServerSideProps (for Server-Side Rendering). These methods let you pre-render pages based on data fetching at build time or request time.
For example:
getStaticProps
is used to fetch data at build time, ideal for static content that doesn’t change frequently.getServerSideProps
fetches data at request time, allowing for server-side rendered content that can be updated on each page load.
4. App Router in Next.js 13+
The App Router introduced in Next.js 13+ leverages the app
directory and offers a more advanced approach to routing, focusing on nested layouts, server-side rendering flexibility, and component composition.
4.1 Folder-Based Routing
The App Router uses a folder-based structure where each directory inside the app
folder represents a route segment. For instance:
app/page.js
corresponds to the/
route.app/about/page.js
corresponds to the/about
route.
This structure allows for more control over layouts and nested routes. In addition to routing, the App Router supports nested layouts, meaning you can define different layouts for different sections of your app.
4.2 Layouts and Nested Layouts
Layouts in the App Router allow you to encapsulate a consistent structure (e.g., header, footer, sidebar) across pages or groups of pages. Layouts are defined in app/layout.js
and can be nested to create complex UI structures:
app/layout.js
would contain the global layout (e.g., header and footer), shared across all pages.app/dashboard/layout.js
would define a layout specifically for the/dashboard
section, potentially with different navigation.
Layouts allow for reusability of common UI elements across different routes, promoting maintainability and clean code.
4.3 Server-Side Rendering (SSR) and Client-Side Rendering (CSR)
The App Router offers fine-grained control over server-side rendering (SSR) and client-side rendering (CSR).
- You can define the rendering behavior for individual pages or components. For example, if a component should only render on the server, you can use the
use server
directive. - The App Router introduces React Suspense for managing data fetching, allowing you to control how content is fetched and displayed, and decide which components should render on the server or the client.
SSR can now be applied at a more granular level, and developers have explicit control over how and when content is rendered, ensuring more optimization.
4.4 Advanced Features: use
and async
Next.js 13 introduces new hooks and patterns for handling data fetching and asynchronous tasks. The use
hook enables components to declaratively fetch data server-side, making it more intuitive than the older getStaticProps
and getServerSideProps
methods.
Additionally, components in the App Router support asynchronous rendering with async
components, enabling better support for dynamic data fetching in complex apps.
5. Key Differences Between Pages Router and App Router
Feature | Pages Router | App Router (Next.js 13+) |
---|---|---|
Directory Structure | Uses pages directory for routing | Uses app directory for routing |
Routing System | File-based routing | Folder-based routing with layouts |
Dynamic Routes | File-based with bracket notation | Folder-based with dynamic routes and layouts |
Layouts | No built-in layout system | Native support for layouts and nested layouts |
Data Fetching | getStaticProps , getServerSideProps | Supports use and async hooks for data fetching |
SSR and CSR | Automatic SSR and CSR | Granular control with server/client-side rendering |
API Routes | Supported in pages/api | Not directly supported in app/api |
Code Splitting and Optimization | Built-in automatic splitting | Enhanced support for optimized code-splitting and lazy loading |
6. When to Use Each Router
Use Pages Router:
- If your project is relatively simple or small, and you don’t need complex layouts or nested routing.
- If you’re migrating from an older Next.js app and prefer to keep the traditional structure.
- If you’re familiar with the Pages Router and don’t require the additional features offered by the App Router.
Use App Router:
- If you’re starting a new Next.js project and need support for complex layouts, nested routing, and more control over SSR/CSR.
- For large applications where modular routing and layout composition are necessary.
- If your project requires advanced features like React Suspense, data fetching with
use
, and enhanced code-splitting and optimization.
7. Migrating from Pages Router to App Router
Migrating from the Pages Router to the App Router involves several steps:
- Move to the
app
Directory: Begin by migrating your existing files from thepages
directory to theapp
directory. Each page should be converted into apage.js
orpage.tsx
file within the appropriate folder. - Refactor Layouts: Instead of defining global components (like navigation) in each page, move them into a common
app/layout.js
file. For sections with different layouts, create nested layout files. - Switch Data Fetching: Replace
getStaticProps
andgetServerSideProps
with React’s new data-fetching mechanisms (use
andasync
). Refactor components to use hooks likeuse
for fetching data. - Test Thoroughly: Since the App Router introduces significant changes, test all routes, layouts, and SSR functionality thoroughly to ensure everything is working as expected.
8. Conclusion
The Pages Router is still relevant and appropriate for simpler applications or for developers who prefer a more traditional, file-based routing system. However, for modern, large-scale Next.js projects, the App Router offers more advanced features, enhanced flexibility, and better control over routing, rendering, and layouts.
Whether to stick with the Pages Router or switch to the App Router depends on the specific needs of your application. For new projects or when scalability and flexibility are critical, the App Router is the recommended choice.