Convert Next.js Pages Router code to the App Router pattern with server components, server actions, and modern data fetching.
Fill in this template
The {{ }} placeholders are variables — drop in your own details, then copy the ready-to-use prompt. (Or copy the template as-is and let your AI assistant fill them in.)
0/2 filled
Preview filled prompt
You are a Next.js migration expert specializing in the Pages Router to App Router transition.
## Pages Router Code
```tsx
{{CODE}}
```
## Page Type
{{PAGE_TYPE}}
(Options: static-page, dynamic-page, api-route, middleware, layout, error-boundary)
## Migration Guide
### 1. File Structure Changes
- `pages/index.tsx` -> `app/page.tsx`
- `pages/about.tsx` -> `app/about/page.tsx`
- `pages/blog/[slug].tsx` -> `app/blog/[slug]/page.tsx`
- `pages/api/users.ts` -> `app/api/users/route.ts`
- `pages/_app.tsx` -> `app/layout.tsx`
- `pages/_document.tsx` -> `app/layout.tsx` (merged)
- `pages/_error.tsx` -> `app/error.tsx`
- `pages/404.tsx` -> `app/not-found.tsx`
### 2. Data Fetching Migration
#### getServerSideProps -> Server Component
```
// Before (Pages Router)
export async function getServerSideProps(context) {
const data = await fetchData(context.params.id);
return { props: { data } };
}
// After (App Router) — just fetch in the component
export default async function Page({ params }) {
const data = await fetchData(params.id);
return <div>{data.title}</div>;
}
```
#### getStaticProps -> Server Component + cache
- Use fetch with `{ cache: 'force-cache' }` or `{ next: { revalidate: 60 } }`
- Or use `unstable_cache` for non-fetch data sources
- Use `generateStaticParams` for `getStaticPaths`
#### Client-side data (useEffect + useState) -> Server Component or 'use client'
- If data can be fetched at request time, use server component
- If data needs real-time updates, use 'use client' with SWR/React Query
### 3. Component Classification
Determine for each component:
- **Server Component** (default): No hooks, no browser APIs, no event handlers
- **Client Component** ('use client'): Uses useState, useEffect, onClick, browser APIs
- **Shared Component**: Can work in both (no hooks, accepts data as props)
### 4. API Routes Migration
```
// Before: pages/api/users.ts
export default function handler(req, res) { ... }
// After: app/api/users/route.ts
export async function GET(request: NextRequest) { ... }
export async function POST(request: NextRequest) { ... }
```
### 5. Common Patterns
- `useRouter()` from 'next/router' -> `useRouter()` from 'next/navigation' (client) or `redirect()`/`notFound()` (server)
- `router.query` -> `params` (path) and `searchParams` (query string)
- `getLayout` pattern -> nested `layout.tsx` files
- `next/head` -> `export const metadata` or `generateMetadata()`
- `next/image` -> same, but check for any deprecated props
- `next/link` -> same, `<a>` child no longer needed
### 6. Metadata Migration
```
// Before: <Head><title>Page Title</title></Head>
// After (static):
export const metadata = { title: 'Page Title' };
// After (dynamic):
export async function generateMetadata({ params }) {
const data = await fetchData(params.id);
return { title: data.title };
}
```
### 7. Loading & Error States
- Add `loading.tsx` for Suspense boundaries
- Add `error.tsx` for error boundaries (must be 'use client')
- Add `not-found.tsx` for 404 handling
## Output Format
1. **File Mapping**: Old path -> new path for each file
2. **Migrated Code**: Complete App Router version of each file
3. **Client/Server Split**: Which components need 'use client' and why
4. **Breaking Changes**: Behavior differences to watch for
5. **Testing Notes**: What to verify after migrationTags
migrationnextjsapp-routerreactserver-components
Explore more prompts and rules
BeforeMerge offers hundreds of AI prompts, code review rules, guides, and detection patterns to help your team ship better code.