SSR, fully dynamic

Every panel below resolves at request time. The probe reads an upstream that returns a different integer on every call, so you do not have to trust the timestamps.

Note what is still static: the heading, this copy, the nav, and every Suspense fallback. Even a page with nothing cached ships a prerendered shell.

What to check

Reload. Every stamp, execution id and probe value changes every time.

Then confirm it from outside the browser: for i in 1 2 3; do curl -s localhost:3000/ssr | grep -o 'data-exec="[^"]*"' | md5; done gives three different digests.

In next dev the probe may look cached anyway, because dev keeps a fetch cache across HMR. Test this one in a build, or set serverComponentsHmrCache: false.

Per-request values

Each of these calls connection() first. Remove that call and the build fails with blocking-prerender-current-time, naming the component. Cache Components refuses to bake a request-time value into static HTML.

Request stamp

suspense fallback

streaming at request time. This is what ships in the static shell.

Live probe

suspense fallback

streaming at request time. This is what ships in the static shell.

Uncached upstreams

Market — uncached

suspense fallback

streaming at request time. This is what ships in the static shell.

Station — uncached

suspense fallback

streaming at request time. This is what ships in the static shell.

Request context

Reading cookies() or headers() no longer makes the whole route dynamic. It defers only this subtree. /ppr shows the same thing on a page with cached content around it.

cookies() and headers()

suspense fallback

streaming at request time. This is what ships in the static shell.

The client router can serve a cached RSC payload on back/forward navigation. Use a real document request when you want to be sure you hit the server: