Skip to the solution
HardSystem Design4 min read

How do you migrate from the Pages Router to the App Router in Next.js?

1.2k views

The problem

Question presented to candidate: "We have a large Pages Router app. How would you plan the migration to the App Router without a big-bang rewrite?"

What a strong answer should cover:

  • Both routers work in one app, so migrate incrementally, route by route; a path must not exist in both.
  • Start with the root layout (app/layout.tsx replaces _app and _document), then move low-risk pages.
  • Replace data functions with Server Component fetching, next/router with next/navigation hooks, next/head with the Metadata API, and API routes with Route Handlers when convenient.
  • Navigation between the two routers is a hard navigation (full page load) and Link does not prefetch across them, so migrate related sections together.
  • Use codemods for mechanical changes and upgrade Next.js first so both routers run on the same version.

Clarifying questions expected:

  • "Which sections are most self-contained?" β€” they migrate first.
  • "Which libraries rely on next/router or _app providers?" β€” they need Client Component wrappers.

Code / implementation expected: Yes β€” a root layout replacing _app and _document, and a page conversion.

  • nextjs
  • migration
  • app-router
  • pages-router

Try it yourself

Sketch your approach before you read the solution. That is what the interview tests.

Stuck? Get a hint.

A short nudge toward the approach. It will not give the answer away.

Solution

The solution is hidden so you can try first

4 min read Β· 8 sections

Read the code

A root layout replacing _app and _document
// app/layout.tsx (replaces pages/_app.tsx and pages/_document.tsx)
import type { Metadata } from "next";
import { Providers } from "./providers";
import "./globals.css";

export const metadata: Metadata = { title: { template: "%s | Shop", default: "Shop" } };

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <body>
        <Providers>{children}</Providers>
      </body>
    </html>
  );
}

// app/providers.tsx
"use client";
import { ThemeProvider } from "@/lib/theme";
export function Providers({ children }: { children: React.ReactNode }) {
  return <ThemeProvider>{children}</ThemeProvider>;
}

Discussion

Other approaches, follow-ups and how it went in real interviews.

Sign in to join the discussion.

No comments yet. Share how you would answer it.

Question 98 of 129 in Next.js

Keep your momentum going.

Mark this question solved to track your progress, then take the next one while it is fresh.

All Next.js questions
Up nextHard

How do Server and Client Components compose in Next.js?

Continue