How does the new App Router in Next.js 13 work

Key takeaways:

  • The App Router introduces advanced features like Server Components, Suspense for streaming UI, and Server Actions, enabling developers to create efficient, server-rendered applications with ease.

  • Unlike the traditional Pages Router, the new App Router leverages folders inside the app directory to define routes, offering more flexibility with nested layouts, dynamic routing, and server-side rendering improvements.

  • The App Router utilizes specific files like layout.js for shared layouts, loading.js to display loading states with Suspense, and error.js to isolate errors within route-specific sections, ensuring a smoother and more responsive user experience.

Next.js is a React-based web framework that simplifies building server-rendered React applications. It supports a file-based routing system, automatically generating routes based on the file structure. Starting with version 13, Next.js introduced the App Router, a modern routing system built on top of React’s latest features. This new router allows developers to create powerful, server-rendered applications using an improved file-based routing approach with capabilities like dynamic routing, nested layouts, and server-side data fetching.

The App Router uses the app directory to define routes and structure the UI. Each folder within the app directory represents a route. Some of the key features of the App Router are:

  • Server Components: It enables developers to build UI components that run on the server, reducing the amount of JavaScript sent to the client.

  • Streaming with Suspense: It allows rendering parts of the UI progressively as data is loaded, improving perceived performance.

  • Server Actions: It allows actions to be executed directly on the server, reducing the complexity of client-side state management.

Learn more about the App Router with this blog, “Understanding Routing in Next.js with the App Router.”

App Router vs. Pages Router

Previously, Next.js used a file-based routing system known as the Pages Router. This system defined the navigation structure of a web application through the contents of the pages directory. Each file within this directory corresponded to a specific route, with nested folders contributing to the route hierarchy. For example, if a home.js file was created inside the pages directory, it would act as the /home route for the website.

File structure for the Pages Router
File structure for the Pages Router

Similar to how files in the pages directory use routing, the App Router in Next.js relies on folders within the app directory to determine routing. A page.js file inside the corresponding folder specifies the user interface for a specific route. As a result, a folder structure such as /app/home/page.js is responsible for rendering the /home route.

File structure for the App Router
File structure for the App Router

Key files in the App Router

The App Router’s functionalities, such as handling loading states, errors, shared UI components, and template management, are handled through the following specific files:

  1. page.js: It defines the main UI for a specific route. This file must be present in every folder to represent the route. It acts as the entry point for each route’s UI, rendering the content that users see when they navigate to that particular path.

  2. loading.js: It is used to handle loading states when navigating between routes. It is wrapped in a React Suspense boundary, which allows it to display a fallback UI while the main content is being loaded. This ensures that users are presented with a visual indication that the page is loading, improving the perceived performance and responsiveness of the application. The loading.js component is particularly useful for handling data fetching scenarios or when rendering complex UIs that take time to load.

To get a hands on experince on Next.js routing refer to the “Build a Music Sharing App with Next.js and the MERN Stack” project.

  1. error.js: It is optional and isolates errors in the app’s small subsections. This file is placed inside the route folders, so whenever an error occurs inside that directory, the error component replaces the page. React error boundary is used to implement this functionality inside Next.js.

  2. layout.js: It is used to create a shared UI across multiple pages. It is particularly useful for elements like headers, footers, or sidebars that need to be displayed across different routes. Unlike regular components, the layout remains mounted during route changes, preserving the state of its child components. This means that the UI will not reset or reload when navigating between different pages within the layout, providing a smoother user experience.

  3. template.js: It functions similarly to the layout.js file, but with one key difference: it does not preserve the state of its child components across route changes. This means that every time a user navigates to a different route, a new instance of the component is mounted, and the state is reset.

Coding example

Let’s look at a working example of using the App Router in an application:

"use client";

export default function MainError() {
  return (
    <div>
      <h1>Something went wrong!</h1>
      <p>We are experiencing some technical issues. Please try again later.</p>
    </div>
  );
}
Using App Router

Code explanation

Let’s understand the code in detail:

  1. The /app/page.js file serves as the entry point for the home page (/).

  2. The /app/layout.js file:

    1. It is the global layout that defines the main navigation and wraps the content of all pages in the application.

    2. The children prop renders the content of each page.

  3. The /app/loading.js file provides a global loading state displayed during the initial load of the application or when navigating between sibling routes.

  4. The /app/error.js file displays a custom error message if something goes wrong in the application.

  5. The /app/courses/layout.js file provides a shared header for all course-related pages, keeping the UI consistent across all course routes.

  6. The /app/courses/error.js file provides a custom error message specific to the courses section if an error occurs while loading course data.

  7. The /app/courses/page.js file lists all available courses and links to individual course detail pages dynamically.

  8. The /app/courses/[id]/page.js file displays the details of a specific course based on the ID parameter from the URL.

  9. The /app/projects/layout.js file provides a shared header for all project-related pages, ensuring a consistent UI across all project routes.

  10. The /app/projects/page.js file lists all available projects, allowing users to explore various learning opportunities.

  11. The /app/projects/error.js file displays a custom error message for the projects section if there is an issue loading the project data.

  12. The /app/projects/template.js file provides a wrapper for the Projects section, ensuring that a new instance of the component is created on each route change and the state is not preserved.

Continue learning Next.js

Explore these projects for hands-on practice on Next.js routing:

Frequently asked questions

Haven’t found what you were looking for? Contact Us


What is the difference between the App Router and the Pages Router in Next.js?

The App Router in Next.js 13 uses the app directory for routing and supports advanced features like Server Components, Suspense, and Server Actions. It allows for a more modular approach to building applications, with files like layout.js, loading.js, and error.js.

The Pages Router uses the pages directory and has been the default routing system in earlier versions of Next.js. While it primarily supports client-side rendering (CSR), it also allows other rendering techniques, such as server-side rendering (SSR) with getServerSideProps, static site generation (SSG) with getStaticProps, and incremental static regeneration (ISR). Both routers support powerful rendering patterns, but the App Router introduces more granular control with React’s latest capabilities.


How do I access dynamic route parameters in the App Router?

In the App Router, dynamic route parameters are accessed using the params prop passed to your component, unlike the useRouter hook used in the Pages Router. For example, in a file located at /app/courses/[id]/page.js, the id parameter can be accessed as params.id.


Can I use both the Pages Router and the App Router in the same project?

Yes, both routers can coexist in the same project. This allows developers to migrate gradually to the App Router while still using the Pages Router for existing functionality. In case a route is defined in both pages and app directory, Next.js prioritizes Pages Router over the App Router.


Free Resources

Copyright ©2025 Educative, Inc. All rights reserved