Files
stack/packages/mosaic/framework/skills/next-best-practices/async-patterns.md
T
fargo 1a822493ba format: apply repo prettier (3.8.1) to the folded skills tree
963 markdown files reformatted with the repository's pinned prettier so
pnpm format:check covers the folded tree like every other repo file.

The formatter's embedded-language pass also normalized code fences
(TS semicolons, closed HTML tags in examples, lowercased CSS hex colors,
one renumbered list that skipped an index). Alphanumeric token deltas vs
the fold commit were audited file-by-file; all are formatter-equivalent
markup normalizations plus the four sanitized skills.
2026-08-19 14:37:17 -05:00

1.6 KiB

Async Patterns

In Next.js 15+, params, searchParams, cookies(), and headers() are asynchronous.

Async Params and SearchParams

Always type them as Promise<...> and await them.

Pages and Layouts

type Props = { params: Promise<{ slug: string }> };

export default async function Page({ params }: Props) {
  const { slug } = await params;
}

Route Handlers

export async function GET(request: Request, { params }: { params: Promise<{ id: string }> }) {
  const { id } = await params;
}

SearchParams

type Props = {
  params: Promise<{ slug: string }>;
  searchParams: Promise<{ query?: string }>;
};

export default async function Page({ params, searchParams }: Props) {
  const { slug } = await params;
  const { query } = await searchParams;
}

Synchronous Components

Use React.use() for non-async components:

import { use } from 'react';

type Props = { params: Promise<{ slug: string }> };

export default function Page({ params }: Props) {
  const { slug } = use(params);
}

generateMetadata

type Props = { params: Promise<{ slug: string }> };

export async function generateMetadata({ params }: Props): Promise<Metadata> {
  const { slug } = await params;
  return { title: slug };
}

Async Cookies and Headers

import { cookies, headers } from 'next/headers';

export default async function Page() {
  const cookieStore = await cookies();
  const headersList = await headers();

  const theme = cookieStore.get('theme');
  const userAgent = headersList.get('user-agent');
}

Migration Codemod

npx @next/codemod@latest next-async-request-api .