100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
JavaScript

The App Router vs Pages Router

A comparison of Next.js's two routing systems — the legacy Pages Router and the modern App Router built on React Server Components.

Next.js FoundationsIntermediate9 min readJul 10, 2026
Analogies

The App Router vs Pages Router

Next.js has shipped two routing systems over its history. The Pages Router, based on the pages/ directory, was the original system and maps each file to a route using getStaticProps and getServerSideProps for data fetching. The App Router, introduced in Next.js 13 and stabilized in 13.4, uses the app/ directory, is built on React Server Components, and supports nested layouts, streaming, and colocated data fetching with async/await directly inside components.

🏏

Cricket analogy: The Pages Router is like Test cricket's traditional format, well-established with fixed rules, while the App Router is like the newer Hundred format, redesigned from first principles with a different structure for a modern audience.

How the Pages Router Works

In the Pages Router, every file under pages/ becomes a route automatically: pages/about.js becomes /about, and pages/index.js becomes /. Data fetching happens through exported functions like getStaticProps (build-time data), getServerSideProps (per-request data), or getStaticPaths (for dynamic routes). Shared UI like a navbar goes in a special _app.js file, and custom document-level HTML structure goes in _document.js.

🏏

Cricket analogy: getStaticProps fetching data at build time is like preparing a scorecard template before the toss, while getServerSideProps is like updating the live scoreboard in real time as each ball is bowled during the innings.

How the App Router Works

The App Router uses folders inside app/ where a page.tsx file marks a route as publicly accessible, and layout.tsx files wrap that route and any nested routes beneath it. Components are React Server Components by default, meaning they can be async and fetch data directly with await without needing getServerSideProps. Special files like loading.tsx and error.tsx automatically create loading and error UI boundaries for that route segment.

🏏

Cricket analogy: A page.tsx marking a route as accessible is like a player being named in the official playing XI — only then do they actually take the field, even though the whole squad exists in the folder.

tsx
// app/layout.tsx (Root layout, required)
export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <body>
        <nav>Site Navigation</nav>
        {children}
      </body>
    </html>
  );
}

// app/dashboard/page.tsx (Server Component, async data fetching)
async function getStats() {
  const res = await fetch('https://api.example.com/stats', { cache: 'no-store' });
  return res.json();
}

export default async function DashboardPage() {
  const stats = await getStats();
  return <section><h1>Dashboard</h1><p>Active users: {stats.activeUsers}</p></section>;
}

Next.js supports incremental adoption: a single project can have both an app/ directory and a pages/ directory at the same time, letting teams migrate route by route instead of rewriting the whole application at once.

Which Should You Choose?

For new projects, the App Router is the recommended default because it unlocks nested layouts, streaming with Suspense, colocated loading and error states, and simpler data fetching without separate lifecycle functions. The Pages Router remains fully supported and is a reasonable choice for maintaining existing applications or when a team relies on ecosystem libraries that assume the Pages Router's data-fetching model.

🏏

Cricket analogy: Choosing the App Router for a new project is like a franchise building its squad around T20 specialists from day one, rather than retrofitting Test-match veterans into a format they weren't developed for.

You cannot define the same URL path in both pages/ and app/ simultaneously — Next.js will throw a build error. When migrating incrementally, move one route at a time and be aware that data-fetching patterns differ significantly: getServerSideProps has no direct App Router equivalent, since data fetching happens via async Server Components instead.

  • The Pages Router uses pages/ with getStaticProps/getServerSideProps for data fetching.
  • The App Router uses app/ and is built on React Server Components.
  • App Router supports nested layouts, streaming, and colocated async data fetching.
  • Both routers can coexist in the same project for incremental migration.
  • The same URL path cannot be defined in both routers at once.
  • App Router is the recommended default for new Next.js projects.
  • Pages Router remains fully supported for existing applications.

Practice what you learned

Was this page helpful?

Topics covered

#JavaScript#NextJsStudyNotes#WebDevelopment#TheAppRouterVsPagesRouter#App#Router#Pages#Works#StudyNotes#SkillVeris