App Router

The App Router is a filesystem-based router in Next.js, a framework for building performant applications. It organizes routes with directories and files in the app directory. Each directory represents a URL segment, while the files define how requests to that route are handled. The App Router supports React Server Components, nested routes, and reusable layouts, among many other features.

App router reserved filenames

Most files in the App Router are not automatically exposed to the internet by Next.js, and instead need to be imported by other files.

The filenames that are reserved for special behavior include:

  1. page.tsx - Renders the default exported React component when a GET request is received at the URL segment defined by the directory.
  2. layout.tsx - Used as the layout for the directory, as well as any children directories. page.tsx is nested as the deepest child node within all parent layouts. Except for the app directory itself which requires a “root layout”, layout.tsx is not necessary.
  3. route.tsx - Implements custom request handlers that skip the default layout and page handling. It is normally used for non-GET requests, although GET requests are supported if desired.
  4. loading.tsx - The sibling or nearest parent loading.tsx renders within its sibling and parent layouts while awaiting any children to complete asynchronous operations.
  5. error.tsx - The sibling or nearest parent error.tsx renders within its sibling and parent layouts when a Javascript error is thrown.

These files establish a clear and organized routing structure.

Differences between app router and pages router

The App Router was introduced in Next.js version 13 in 2022, and is considered the successor to the Pages Router. The App Router offers more advanced capabilities and flexibility than the Pages Router.

File structure and convention

Both the Pages Router and App Router use a filesystem-driven router. However, the Pages Router uses a pages directory with a different file- and directory- naming convention for routing.

Routing flexibility

The App Router supports advanced routing capabilities like route groups, parallel routes, and intercepting routes, which do not have native support in the Pages Router.

Simplified data loading

The App Router supports React Server Components, where data can be loaded simply by calling fetch() within a component. The Pages Router requires the use of getServerSideProps and a serialization layer, which adds significant complexity to data loading.

Performance optimization

The directory structure and server-driven nature of the App Router enables Next.js to reduce waterfalls during page loading, and cache individual route segments, which leads to higher performance applications. The App Router also supports streaming for faster loading speeds.

Migration considerations

A single application can use the App Router and Pages Router at the same time, which enables developers to migrate page-by-page more easily.

For more in-depth understanding, visit the Next.js documentation.

Implementation and usage

Create routes in the App Router by adding directories and files in the app folder. The hierarchy corresponds directly to address paths.

Basic route creation

// app/blog/page.tsx

export default function BlogPage() {
  return (
    <div>
      <h1>Blog Posts</h1>
      <p>Welcome to our blog section</p>
    </div>
  )
}

This file creates a route at /blog with a welcome page.

Dynamic routes

Dynamic routes accept parameters by using brackets in the directory name:

// app/posts/[id]/page.tsx

export default function Post({ params }) {
  return <h1>Post: {params.id}</h1>
}

This design handles routes like /posts/1.

Layouts and nesting

The App Router provides shared layouts with a layout.tsx file. The "root layout" is the top-most layout and must contain the <html> tag:

// app/layout.tsx

export default function RootLayout({ children }) {
  return (
    <html>
      <body>
        <nav>{/* Navigation components */}</nav>
        {children}
        <footer>{/* Footer content */}</footer>
      </body>
    </html>
  )
}

Integration with Clerk

The App Router works with Clerk's authentication system for user management. Clerk middleware and helpers we're all designed to integrate well with the App Router.

Authentication implementation

// middleware.ts
import { clerkMiddleware } from '@clerk/nextjs/server'
export default clerkMiddleware()
export const config = {
  matcher: [
    // Skip Next.js internals and all static files, unless found in search params
    '/((?!_next|[^?]*\\.(?:html?|css|js(?!on)|jpe?g|webp|png|gif|svg|ttf|woff2?|ico|csv|docx?|xlsx?|zip|webmanifest)).*)',
    // Always run for API routes
    '/(api|trpc)(.*)',
  ],
}
// app/dashboard/page.tsx
import { auth } from '@clerk/nextjs/server'

export default async function DashboardPage() {
  const { userId } = await auth()
  if (!userId) {
    return <div>Not signed in</div>
  }

  return <div>Protected Dashboard Content</div>
}

Performance and optimization

The App Router enhances application performance through:

  1. Automatic code splitting based on routes.
  2. Built-in data caching and revalidation.
  3. Parallel route rendering.
  4. Streaming Server-Side Rendering (SSR).

These features create faster, more responsive applications while reducing server load.

Building for the future

The App Router is a solid base for modern web apps. Learn its concepts for maintaining and optimizing apps. For more detailed documentation, visit the Next.js documentation and our Next.js Overview.