Dynamic APIs

APIs That Opt Into Dynamic Rendering

APIWhy it is dynamic
cookies()Cookies differ per user
headers()Headers differ per request
searchParams propQuery string is known only at request time
connection()Explicitly wait for a real request (e.g. before Math.random() or Date.now())
draftMode()CMS preview

Note: All of these are async in Next.js 15+: (await cookies()).get('x').

Seeing the Effect

// app/page.tsx
import { headers } from 'next/headers';

export default async function Home() {
  const ua = (await headers()).get('user-agent') ?? '';
  const isMobile = /Android|iPhone/i.test(ua);
  return <p>{isMobile ? 'Get the app for extra 10% off' : 'Welcome to ShopEase'}</p>;
}

Example

The home page was static (○); now it is dynamic (ƒ):

npm run build

Example output

Route (app)                         Size  First Load JS
┌ ƒ /                                512 B         102 kB

Tip: Move the dynamic read into a small component inside <Suspense> (with PPR) or into a Client Component, so the rest of the page stays static.

Forcing a Mode

export const dynamic = 'error'; // build fails if anything makes this route dynamic: guards a page you expect to be static