Migration Guide
Guide for migrating from older versions or other frameworks.
From Next.js Pages Router to App Router
File Structure Changes
Before (Pages Router):
pages/
├── index.tsx
├── about.tsx
└── api/
└── hello.ts
After (App Router):
app/
├── page.tsx
├── about/
│ └── page.tsx
└── api/
└── hello/
└── route.ts
Route Changes
Before:
// pages/about.tsx
export default function About() {
return <div>About</div>;
}
After:
// app/about/page.tsx
export default function About() {
return <div>About</div>;
}
API Routes
Before:
// pages/api/hello.ts
export default function handler(req, res) {
res.json({ message: 'Hello' });
}
After:
// app/api/hello/route.ts
export async function GET() {
return NextResponse.json({ message: 'Hello' });
}
Metadata
Before:
import Head from 'next/head';
export default function Page() {
return (
<>
<Head>
<title>My Page</title>
</Head>
<div>Content</div>
</>
);
}
After:
import type { Metadata } from 'next';
export const metadata: Metadata = {
title: 'My Page',
};
export default function Page() {
return <div>Content</div>;
}
From Create React App
Installation
# Remove CRA dependencies
npm uninstall react-scripts
# Install Next.js
npm install next react react-dom
Configuration
Before (CRA):
public/index.htmlsrc/directory- Webpack config (hidden)
After (Next.js):
app/directorypublic/directorynext.config.ts
Routing
Before (React Router):
import { BrowserRouter, Route } from 'react-router-dom';
<BrowserRouter>
<Route path="/about" component={About} />
</BrowserRouter>
After (Next.js):
// app/about/page.tsx
export default function About() {
return <div>About</div>;
}
Environment Variables
Before:
REACT_APP_API_URL=https://api.example.com
After:
NEXT_PUBLIC_API_URL=https://api.example.com
From Other Frameworks
From Vue.js
Component Structure:
// Vue
<template>
<div>{{ message }}</div>
</template>
<script>
export default {
data() {
return { message: 'Hello' };
},
};
</script>
// React/Next.js
export default function Component() {
const [message, setMessage] = useState('Hello');
return <div>{message}</div>;
}
From Angular
Component Structure:
// Angular
@Component({
selector: 'app-component',
template: '<div>{{ message }}</div>',
})
export class Component {
message = 'Hello';
}
// React/Next.js
export default function Component() {
const [message, setMessage] = useState('Hello');
return <div>{message}</div>;
}
Version Upgrades
Upgrading Dependencies
# Check for updates
npm outdated
# Update all dependencies
npm update
# Update specific package
npm install package@latest
Breaking Changes
Check the CHANGELOG.md for breaking changes between versions.
Testing After Upgrade
- Run tests:
npm test - Check build:
npm run build - Test locally:
npm start - Review console for warnings
Common Migration Issues
Import Path Changes
Before:
import Component from '../components/Component';
After:
import Component from '@/components/Component';
CSS Modules
Before:
import styles from './Component.module.css';
After:
// Same in Next.js App Router
import styles from './Component.module.css';
Client Components
Before:
// All components were client-side
export default function Component() {
return <div>Content</div>;
}
After:
// Server Component (default)
export default function Component() {
return <div>Content</div>;
}
// Client Component (when needed)
'use client';
export default function Component() {
const [state, setState] = useState();
return <div>Content</div>;
}
Migration Checklist
- [ ] Update file structure
- [ ] Convert routes
- [ ] Update API routes
- [ ] Convert metadata
- [ ] Update imports
- [ ] Add 'use client' where needed
- [ ] Update environment variables
- [ ] Test all features
- [ ] Update documentation
- [ ] Deploy and verify
Getting Help
If you encounter issues during migration:
- Check Troubleshooting Guide
- Review Documentation
- Open an issue on GitHub