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
pagesdirectory. - App Router (Introduced in Next.js 13): A new, more flexible routing system introduced in Next.js 13, leveraging the
appdirectory 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.jscorresponds to the/route.pages/about.jscorresponds to the/aboutroute.pages/contact.jscorresponds to the/contactroute.- 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].jsmaps to/blog/1,/blog/2, etc., and you can access the dynamicidusinguseRouter().
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.jsmaps 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:
getStaticPropsis used to fetch data at build time, ideal for static content that doesn’t change frequently.getServerSidePropsfetches 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.jscorresponds to the/route.app/about/page.jscorresponds to the/aboutroute.
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.jswould contain the global layout (e.g., header and footer), shared across all pages.app/dashboard/layout.jswould define a layout specifically for the/dashboardsection, 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 serverdirective. - 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
appDirectory: Begin by migrating your existing files from thepagesdirectory to theappdirectory. Each page should be converted into apage.jsorpage.tsxfile within the appropriate folder. - Refactor Layouts: Instead of defining global components (like navigation) in each page, move them into a common
app/layout.jsfile. For sections with different layouts, create nested layout files. - Switch Data Fetching: Replace
getStaticPropsandgetServerSidePropswith React’s new data-fetching mechanisms (useandasync). Refactor components to use hooks likeusefor 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.

