Skip to content

Pages to App Migration

Migrating from Pages to App Router

Migrating from Next.js Pages Router to the App Router involves reorganizing your project structure, adopting new routing semantics, and leveraging the App Router’s capabilities for nested layouts, parallel routing, and improved performance. This guide provides a structured approach to the migration process.


Step 1: Set Up the App Directory

The App Router uses a nested directory structure under app/ to define routes. Begin by creating the app/ directory if it doesn’t already exist.

mkdir -p app/

Note: The app/ directory replaces the old pages/ directory. All route definitions now live here.


Step 2: Migrate Pages to App Router

2.1. Static Pages

For a static page like pages/about.js, create a corresponding file in app/about/page.tsx:

// app/about/page.tsx
export default function About() {
  return <div>About Page</div>;
}

2.2. Dynamic Routes

For dynamic routes like pages/posts/[id].js, structure the App Router as follows:

app/posts/[id]/page.tsx
// app/posts/[id]/page.tsx
export default function Post({ params }) {
  const { id } = params;
  return <div>Post ID: {id}</div>;
}

Step 3: Implement Layouts

The App Router requires layout.tsx files to define shared UI across nested routes. For example:

// app/layout.tsx
export default function Layout({ children }) {
  return (
    <div>
      <header>Shared Header</header>
      <main>{children}</main>
      <footer>Shared Footer</footer>
    </div>
  );
}

Tip: Use layout.tsx in parent directories to apply layouts to all child routes.


Step 4: Handle API Routes

Move API routes from pages/api/ to app/api/:

mv pages/api/hello.js app/api/hello.ts

Update the file to use the new API route syntax:

// app/api/hello.ts
export default function handler(req: Request) {
  return new Response("Hello from App Router!");
}

Update internal links to use the new routing syntax:

// Old (Pages Router)
<Link href="/about">About</Link>

// New (App Router)
<Link href="/about">About</Link>

Use the next/link component with the correct route paths.


Step 6: Test and Validate

Run the development server and verify all routes:

npm run dev

Check for:
- Correct rendering of dynamic routes
- Proper layout inheritance
- API route functionality


Key takeaways

  • Reorganize your project into the app/ directory with nested routes.
  • Use layout.tsx to share UI across nested routes.
  • Update links and navigation to reflect the new routing syntax.
  • Test thoroughly to ensure all pages and API routes work as expected.
  • Leverage App Router features like parallel routing and server components for scalability.