Skip to content
instant.by-design
Home

Cheat sheet

Every rule and API from the course, in one place. Use it after you read the lessons.

The three content types

  • Static

    Prerendered at build time. Ships from the edge. No data read.

  • Cached

    Wrapped in use cache. Reused across requests until it revalidates.

  • Dynamic

    Read per request. Wrapped in Suspense. Streams in after the shell.

Quick start

Enable both flags in the config. Every route becomes prerenderable.

next.config.tstsx
// next.config.tsexport default {  cacheComponents: true,  partialPrefetching: true,}

use cache placement

  • File: first line, caches the whole render.
  • Component: first line of the body.
  • Function: first line, caches the return value.
lib/data.tstsx
import { cacheLife, cacheTag } from 'next/cache' async function getData(id: string) {  'use cache'  cacheLife('hours')  cacheTag('items', `item-${id}`)  return db.items.findUnique({ where: { id } })}

Lifetime with cacheLife

  • Profiles: minutes, hours, days, weeks, max.
  • Or exact seconds: { stale, revalidate, expire }.
  • No request data means the cache fills at build time.

Invalidation

  • updateTag(tag) — immediate, read-your-writes.
  • revalidateTag(tag, 'max') — background refresh.
  • refresh() — refresh uncached data only.

Runtime data rule

You cannot read cookies(), headers(), or searchParams inside 'use cache'. Read the value outside, then pass it in as an argument. The exception is 'use cache: private' for per user data.

Instant navigation rules

  • Push each Suspense boundary down to the data it guards.
  • Hoist any element that appears in both the fallback and the result.
  • Keep the main heading out of every boundary.
  • A top-level await blocks the whole subtree.

Page load vs client nav

  • Page load: whole tree renders. Ships the static shell as HTML.
  • Client nav: only parts below the shared layout re-render.
  • A boundary must sit below the lowest shared layout to cover both.
  • useSearchParams() suspends on load, resolves on client nav.

Prefetch choice

  • Default <Link> warms the shared App Shell.
  • prefetch={true} resolves URL data before the click.
  • Link = intent. The prefetch export = cost ceiling.
  • For dense lists, prefetch on hover, not on view.

prefetch segment config

  • 'auto' — the default. Do not write it out.
  • 'partial' — adopt one route without the global flag.
  • 'force-disabled' — never prefetch this or deeper segments.
  • instant = false — the route is dynamic by design.

Session data in the shell

  • A route reading cookies() gets session data in its shell.
  • Extract and pass: read the cookie outside, pass it into 'use cache'. Shared entry.
  • 'use cache: private': reads runtime data inside, cached in the browser only.
  • Private cache needs stale of at least 5 minutes to ride the shell.

Validate and test

  • Dev overlay validates every page. Fix cards: Stream, Cache, Block.
  • Navigation Inspector freezes the shell so you can see it.
  • instant() from @next/playwright scopes assertions to instant UI.
  • Test both a page load and a client navigation.

Migration map

Old API to new API
OldNew
experimental.pprcacheComponents: true
dynamic = 'force-dynamic'remove it (dynamic is the default)
dynamic = 'force-static''use cache' + cacheLife('max')
revalidate = NcacheLife({ revalidate: N })
unstable_cache()'use cache' directive

Want to start over? Return to lesson 1.