Study notes · 10% of the exam

Rendering Strategies and Streaming

Next.js decides per route (previous model) or per component (Cache Components) what is prerendered at build time and what renders at request time, then streams the result through Suspense boundaries.

Key points

  1. 1

    Without Cache Components, one request-time API (cookies(), headers(), searchParams, draftMode()) or uncached fetch makes the whole route dynamic (ƒ); segment config like dynamic, revalidate and dynamicParams tunes this.

  2. 2

    With cacheComponents: true, Partial Prerendering is the default: static markup, 'use cache' results and Suspense fallbacks form a static shell (◐), and runtime or uncached parts stream in. dynamic, revalidate, fetchCache and dynamicParams are removed.

  3. 3

    <Suspense> gives a fallback but does not make work dynamic. Use await connection() for per-request values such as Math.random() or synchronous DB reads.

  4. 4

    ISR serves the stale page after the window and regenerates in the background. The lowest revalidate in the route wins, a no-store or revalidate: 0 fetch makes it dynamic, and failed regenerations keep the last good page.

  5. 5

    Once streaming starts, the status (200) and headers are fixed: mid-stream notFound() adds a noindex meta tag and redirect() becomes client-side. Check existence before any Suspense boundary for a real 404.

  6. 6

    Client Components are prerendered to HTML and hydrated. Locale and time formatting cause hydration mismatches; fix them with an inline script plus suppressHydrationWarning on each corrected element.

  7. 7

    HTML-limited bots skip the shell and get a full request-time render, so anything the shell needs must also exist at request time.

Common traps

  • Returning [] from generateStaticParams means "render on first visit" without Cache Components, but it is a build error with Cache Components (return at least one param).

  • loading.js does not wrap its own segment's layout.js, template.js or error.js, so a slow layout is not covered by its own loading UI.

  • next/dynamic with ssr: false only works inside a Client Component, and runtime = 'edge' is deprecated and unsupported with Cache Components.

Test yourself on Rendering Strategies and Streaming

Ten questions, with the answer and explanation after each one.