How do I migrate to new async request APIs in next 15?
In Next.js 15, there's a significant change to how certain APIs that rely on request-specific data are handled. These APIs are now asynchronous, which is a breaking change 1. Here's how you can migrate to the new async request APIs:
Affected APIs: The following APIs are now asynchronous 1:
cookies
headers
draftMode
params
in layout.js
, page.js
, route.js
, default.js
, generateMetadata
, and generateViewport
searchParams
in page.js
Migration Steps: a. Use the provided codemod to automate the migration process 1:
npx @next/codemod@canary next-async-request-api .
b. For cases where the codemod can't fully migrate your code, you'll need to manually update your code.
Example of manual migration for cookies
:
Before:
import { cookies } from 'next/headers'
const cookieStore = cookies()
const token = cookieStore.get('token')
After:
import { cookies } from 'next/headers'
const cookieStore = await cookies()
const token = cookieStore.get('token')
For params
in layouts:
Before:
export default function Layout({
children,
params,
}: {
children: React.ReactNode
params: { slug: string }
}) {
const { slug } = params
}
After:
export default async function Layout({
children,
params,
}: {
children: React.ReactNode
params: Promise<{ slug: string }>
}) {
const { slug } = await params
}
Temporary Synchronous Usage: If you need to temporarily access these APIs synchronously, you can do so, but it will show warnings in development and production until the next major version 1. For example:
import { cookies, type UnsafeUnwrappedCookies } from 'next/headers'
const cookieStore = cookies() as unknown as UnsafeUnwrappedCookies
// will log a warning in dev
const token = cookieStore.get('token')
Remember, this change is part of Next.js's effort to enable future optimizations and prepare the server to render as much as possible before a request arrives 21.
If you need more specific guidance on migrating a particular part of your application, feel free to ask!