
Fix “params should be awaited” in Next.js App Router
Fix the Next.js “params should be awaited” error in App Router pages and layouts, with safe TypeScript patterns and a migration checklist.
In Next.js 15 and later, dynamic route params are asynchronous. The direct code change is small, but pages, layouts, and metadata generators all need the correct Promise shape.
Resolve params at the server boundary
Make the page or layout async, await params once, then pass plain values to the rest of the application.
params.slugSync access fails in Next.js 15+const { slug } = await paramsResolve once at the server boundarytype PageProps = { params: Promise<{ slug: string }> }
export default async function Page({ params }: PageProps) {
const { slug } = await params
const post = await getPost(slug)
return <Article post={post} />
}Update generateMetadata too
Metadata often gets missed because it is not visible in the page UI. Await params before loading a title, description, canonical URL, or Open Graph data.
type Props = { params: Promise<{ slug: string }> }
export async function generateMetadata({ params }: Props) {
const { slug } = await params
return { title: (await getPost(slug)).title }
}Keep Client Components synchronous
Prefer resolving the Promise in a Server Component and passing plain data down. Use React’s use API only where a Promise genuinely must cross a client boundary.
Verify the whole route
rg "\b(params|searchParams)\b" app src
npm run lint
npm run buildTest a real dynamic route in a production build, including its metadata and 404 behavior. This catches the remaining synchronous access paths.
If the upgrade also left a page visually broken, use the Next.js CSS troubleshooting guide to isolate imports, modules, Tailwind output, and production assets.
Sources and further reading
- Dynamic APIs are Asynchronous · Vercel
- Upgrading: Version 15 · Vercel
- Dynamic Routes · Vercel