You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

320 lines
7.6 KiB
Markdown

# Next.js 15 Upgrade Guide
## Overview
This guide provides comprehensive instructions for upgrading from Next.js 13 to Next.js 15, covering breaking changes, new features, and migration strategies for professional developers.
## Quick Start
### Automated Upgrade (Recommended)
```bash
npx @next/codemod@canary upgrade latest
```
### Manual Upgrade
```bash
npm install next@latest react@latest react-dom@latest
# or with force flag if peer dependency warnings
npm install next@latest react@latest react-dom@latest --force
```
## Breaking Changes
### 1. Async Request APIs ⚠️ **CRITICAL**
APIs like `cookies()`, `headers()`, `draftMode()`, `params`, and `searchParams` are now async.
**Before (Next.js 13):**
```typescript
// layout.tsx, page.tsx, route.ts
export default function Page({ params, searchParams }) {
const cookieStore = cookies();
const headersList = headers();
// ...
}
```
**After (Next.js 15):**
```typescript
// layout.tsx, page.tsx, route.ts
export default async function Page({ params, searchParams }) {
const cookieStore = await cookies();
const headersList = await headers();
const resolvedParams = await params;
const resolvedSearchParams = await searchParams;
// ...
}
```
**Codemod Available:**
```bash
npx @next/codemod@canary next-async-request-api .
```
### 2. Runtime Configuration
**Before:**
```javascript
export const runtime = 'experimental-edge';
```
**After:**
```javascript
export const runtime = 'edge';
```
### 3. Font Imports
**Before:**
```typescript
import { Inter } from '@next/font/google';
```
**After:**
```typescript
import { Inter } from 'next/font/google';
```
### 4. Geolocation in NextRequest
**Before:**
```typescript
// middleware.ts
export function middleware(request: NextRequest) {
const { geo, ip } = request;
// ...
}
```
**After:**
```typescript
import { geolocation, ipAddress } from '@vercel/functions';
export function middleware(request: NextRequest) {
const geo = geolocation(request);
const ip = ipAddress(request);
// ...
}
```
## New Caching Semantics
### Default Behavior Changes
- `fetch` requests are **uncached by default** (was cached)
- GET Route Handlers are **uncached by default**
- Client navigations are **uncached by default**
### Opt-in to Caching
```typescript
// Force static caching for specific routes
export const dynamic = 'force-static';
// Or configure in next.config.ts
const nextConfig = {
experimental: {
staleTimes: {
dynamic: 30, // 30 seconds
static: 180, // 3 minutes
},
},
};
```
## New Features
### 1. React 19 Support
- App Router uses React 19 RC
- Pages Router remains on React 18 for compatibility
- React Compiler support (experimental)
```typescript
// next.config.ts
const nextConfig = {
experimental: {
reactCompiler: true,
},
};
```
### 2. Turbopack for Development (Stable)
```bash
# 76.7% faster local server startup
# 96.3% faster code updates with Fast Refresh
# 45.8% faster initial route compile
next dev --turbo
```
### 3. Static Route Indicator
Visual indicator in development to identify static vs dynamic routes.
```typescript
// next.config.ts - to disable
const nextConfig = {
devIndicators: {
appIsrStatus: false,
},
};
```
### 4. `unstable_after` API (Experimental)
Schedule work after response completion:
```typescript
import { unstable_after as after } from 'next/server';
export default function Layout({ children }) {
after(() => {
// This runs after the response is sent
console.log('Logged after response');
});
return <>{children}</>;
}
```
Enable in config:
```typescript
// next.config.ts
const nextConfig = {
experimental: {
after: true,
},
};
```
### 5. Enhanced `<Form>` Component
```typescript
import Form from 'next/form';
export default function SearchForm() {
return (
<Form action="/search">
<input name="query" placeholder="Search..." />
<button type="submit">Search</button>
</Form>
);
}
```
### 6. Instrumentation.js (Stable)
```typescript
// instrumentation.ts
export function onRequestError(err, request, context) {
console.error('Request error:', err, request.url);
}
```
### 7. Self-Hosting Improvements
```typescript
// next.config.ts
const nextConfig = {
// Configure ISR expiration (default: 1 year)
expireTime: 60 * 60 * 24 * 30, // 30 days
};
```
### 8. Security Enhancements
- Server Actions now have secure, unguessable IDs
- Dead code elimination for unused Server Actions
- Treated as public HTTP endpoints
### 9. Bundling Optimization
```typescript
// next.config.ts
const nextConfig = {
// App Router: external packages bundled by default
serverExternalPackages: ['package-to-exclude'],
// Pages Router: opt-in bundling
bundlePagesRouterDependencies: true,
transpilePackages: ['package-to-bundle'],
};
```
### 10. ESLint 9 Support
```bash
# Migrate to flat config
ESLINT_USE_FLAT_CONFIG=false npm run lint
```
## Migration Checklist
### Pre-Migration
- [ ] Backup your project
- [ ] Review breaking changes
- [ ] Update TypeScript types: `@types/react@latest @types/react-dom@latest`
- [ ] Test in development environment
### During Migration
- [ ] Run automated upgrade: `npx @next/codemod@canary upgrade latest`
- [ ] Update async request APIs (use codemod)
- [ ] Fix runtime configurations
- [ ] Update font imports
- [ ] Handle geolocation changes
- [ ] Review caching behavior
### Post-Migration
- [ ] Test all routes and functionality
- [ ] Enable Turbopack: `next dev --turbo`
- [ ] Configure new caching semantics
- [ ] Explore React 19 features
- [ ] Update ESLint configuration
- [ ] Performance testing
## Common Issues & Solutions
### 1. Peer Dependency Warnings
```bash
npm install --legacy-peer-deps
# or
npm install --force
```
### 2. TypeScript Errors with Async APIs
Ensure all request API calls are awaited and functions are marked async.
### 3. Caching Behavior Changes
If experiencing performance issues, opt-in to caching:
```typescript
export const dynamic = 'force-static';
```
### 4. React 19 Compatibility
Some third-party packages may not be React 19 compatible yet. Consider:
- Checking package compatibility
- Using Pages Router for problematic components
- Waiting for package updates
## Performance Improvements
### Development
- **Turbopack**: 76.7% faster server startup
- **Fast Refresh**: 96.3% faster code updates
- **Route Compilation**: 45.8% faster initial compile
### Production
- **Bundle Optimization**: Automatic external package bundling
- **Security**: Enhanced Server Actions with dead code elimination
- **Caching**: More predictable caching behavior
## Resources
### Official Documentation
- [Next.js 15 Upgrade Guide](https://nextjs.org/docs/app/guides/upgrading/version-15)
- [Next.js 15 Blog Post](https://nextjs.org/blog/next-15)
- [React 19 Upgrade Guide](https://react.dev/blog/2024/04/25/react-19-upgrade-guide)
### Tools & Codemods
- [Next.js Codemods](https://nextjs.org/docs/app/building-your-application/upgrading/codemods)
- [Turbopack Documentation](https://nextjs.org/docs/app/api-reference/next-config-js/turbo)
### Community Resources
- [Migration Examples](https://github.com/leerob/next-saas-starter/pull/62)
- [ESLint 9 Migration](https://eslint.org/docs/latest/use/migrate-to-9)
## Summary
Next.js 15 represents a significant evolution with:
- **Async Request APIs** requiring code changes
- **Improved caching semantics** with opt-in behavior
- **React 19 support** with new features
- **Turbopack stability** for faster development
- **Enhanced security** and performance optimizations
The upgrade process is well-supported with automated tools and codemods, making the transition manageable for most projects. Focus on testing async API changes and reviewing caching behavior for the smoothest upgrade experience.