Softechinfra
Development

Next.js App Router Migration: Step-by-Step Guide

Migrate from Next.js Pages Router to App Router. Learn server components, new data fetching patterns, and incremental adoption strategies.

Hrishikesh BaidyaHrishikesh Baidya
April 1, 20239 min read
Next.js App Router Migration: Step-by-Step Guide

Next.js 13+ introduced the App Router, a new paradigm for building React applications. As CTO of Softechinfra, I've migrated multiple production apps. Migration requires careful planning. Here's how to do it right.

40%
Smaller Bundles
RSC
Server Components Default
2x
Faster TTI
∞
Streaming Support

Understanding the Changes

Pages Router vs App Router

    Pages Router:
  • File-based routing in /pages
  • getStaticProps, getServerSideProps
  • Client-side by default
  • Familiar patterns
    App Router:
  • File-based routing in /app
  • Server Components by default
  • async/await in components
  • New data fetching patterns

Key Differences

    Routing:
  • page.tsx instead of index.tsx
  • layout.tsx for shared layouts
  • loading.tsx for suspense
  • error.tsx for error boundaries
    Data Fetching:
  • fetch() with caching
  • No getStaticProps/getServerSideProps
  • Server Components for data
  • Streaming and Suspense

Migration Strategy

1. Incremental Adoption

    Don't rewrite everything:
  • Both routers work together
  • Migrate page by page
  • Test thoroughly
  • Roll back if needed

2. Start Simple

    Begin with:
  • Static pages
  • Simple components
  • Low-risk areas
  • Well-tested functionality

3. Pattern Translation

Data fetching:

typescript
// Pages Router
export async function getStaticProps() {
  const data = await fetch('...')
  return { props: { data } }
}

// App Router
async function Page() {
  const data = await fetch('...')
  return <Component data={data} />
}

Dynamic routes:

typescript
// Pages Router
// pages/posts/[id].tsx

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

Component Migration

Server Components

    Default in App Router:
  • Can be async
  • No useState/useEffect
  • Direct data fetching
  • Smaller bundles

Client Components

    Mark with 'use client':
  • Interactive elements
  • Browser APIs
  • Hooks (useState, useEffect)
  • Event handlers

Composition Pattern

typescript
// Server Component
import { ClientButton } from './ClientButton'

async function ServerPage() {
  const data = await getData()
  return (
    <div>
      <h1>{data.title}</h1>
      <ClientButton onClick={handleClick} />
    </div>
  )
}

// Client Component
'use client'
export function ClientButton({ onClick }) {
  return <button onClick={onClick}>Click</button>
}

Layout Migration

New Layout System

typescript
// app/layout.tsx - Root layout
export default function RootLayout({ children }) {
  return (
    <html>
      <body>
        <Header />
        {children}
        <Footer />
      </body>
    </html>
  )
}

// app/dashboard/layout.tsx - Nested layout
export default function DashboardLayout({ children }) {
  return (
    <div>
      <Sidebar />
      <main>{children}</main>
    </div>
  )
}

Common Challenges

1. Third-Party Libraries

    Some libraries need updates:
  • Check compatibility
  • Use 'use client' wrapper
  • Find alternatives if needed
  • Report issues to maintainers

2. Hooks Usage

    Server Components can't use hooks:
  • Move to Client Components
  • Use composition pattern
  • Rethink data flow

3. CSS Solutions

    Some approaches change:
  • CSS Modules work fine
  • Tailwind works fine
  • CSS-in-JS may need updates
  • Check library docs

Migration Checklist

    Preparation:
  • [ ] Update to latest Next.js
  • [ ] Review breaking changes
  • [ ] Plan migration order
  • [ ] Set up parallel testing
    Execution:
  • [ ] Create /app directory
  • [ ] Add root layout
  • [ ] Migrate pages incrementally
  • [ ] Test each migration
    Completion:
  • [ ] Remove /pages when done
  • [ ] Update documentation
  • [ ] Performance testing
  • [ ] Monitor production

Migrating to App Router?

Our Next.js team has helped many teams make the transition smoothly. From planning to execution, we've got you covered.

Get Free Consultation
Tags:
Next.jsReactMigrationWeb DevelopmentServer Components
Share this post:
Hrishikesh Baidya

Hrishikesh Baidya

CTO at Softechinfra specializing in Python, system architecture, and building secure, scalable software solutions.