mirror of
https://github.com/vercel/flags.git
synced 2026-09-19 03:49:23 +08:00
a41fa47627
Audited every path through the function returned by `flag()` for whether
it opts the caller out of the prerender. No `await connection()` turned
out to be necessary:
- App Router (`flagFn()`, and `evaluate()` without a request) awaits
`headers()` and `cookies()` before calling `decide`. Those are
Request-time APIs, so awaiting a flag already has the effect of
`connection()`. Adding it would mean importing `next/server` — which
`flags/next` avoids at the top level to keep working in Pages Router —
and awaiting one more promise per evaluation, with no change in
behavior.
- The per-request evaluation cache is keyed by the sealed headers object,
so a cache read can only be reached after that request-time read. It
needs no `connection()` of its own.
- Pages Router and routing middleware are handed a request by the caller
and are request-scoped by definition. `connection()` is App Router-only.
- Reading a precomputed value and `evaluate([])` deliberately read
nothing from the request. Adding `connection()` there would break the
entire point of precompute, which is keeping pages prerenderable.
Since the guarantee comes from the SDK rather than from any individual
`decide`, it is easy to break by accident, so this locks it in:
- `packages/flags/src/next/dynamic-rendering.test.ts` asserts which paths
read `headers()`/`cookies()` and which must not — including cache hits,
overrides, bulk evaluation, and precomputed reads.
- `tests/next-1{5,6}` gain an `/app-router-dynamic` route rendering a flag
whose `decide` ignores the request and returns a new value every time.
Next 15 reports it as `ƒ (Dynamic)`, Next 16 (Cache Components) streams
it outside the shell, and an e2e test asserts two requests differ. On
Next 16 the build itself is an assertion: without the SDK's request read
it fails with `next-prerender-random`.
Also documents the behavior for users, in the `flags/next` API reference
and the flags-sdk skill, so nobody adds `await connection()` in front of
a flag evaluation.
No runtime change, hence no changeset.
Co-Authored-By: Dominik Ferber <1765075+dferber90@users.noreply.github.com>