Exposures
Why results count only people who saw a version, the four exposure policies, and who is never counted.
An exposure is the record that a person actually saw a version of a test. Exposures are the denominator of every result: a person who was assigned a version but never saw it is not counted, and neither are their conversions.
Reading is not seeing
Reading an assignment, calling getFlagPoint, or calling useExperiment never records an exposure. Only the calls described below do.
Why it matters
Assignment happens in the proxy for every eligible request. If results counted assignments, a visitor who never scrolled to the tested block, or never reached the tested page, would dilute both groups equally and hide real differences. Counting exposures keeps the comparison to the people the change could affect.
Exposure policies
Each test kind uses one or two policies:
| Policy | Used by | Recorded when | Recorded by |
|---|---|---|---|
render | Block tests | The resolved block is rendered on the server | recordExposures(serverRuntime, rendered, assignments) in after() |
viewport | Block tests | At least half of a 100 px marker at the top of the block is visible | The client provider |
pageview | Page tests | The target page appears, including after client navigation | <ExperimentPageview /> inside a provider |
manual | Flag and code tests | Your code says the version was delivered | point.expose(arm) or expose(arm) from a hook |
For render, pass only the rendered list returned by resolveExperimentData or resolveExperimentBlocks to recordExposures, never the whole assignment map. That list contains only the block tests actually present in the content you rendered.
Who is never counted
These requests produce no exposures:
- Staff, when you identify them through
attributesOf(see Signed-in users). - Bots matched by the built-in user-agent list.
- Preview renders opened with a signed preview token.
HEADrequests.- Requests where consent was declined (when you configure
cookie.consent). - People outside the test's allocation or targeting. They see the Original without being counted.
The proxy also skips admin, API, Next.js internal and asset paths. Your own editor renders must stay out of exposure recording.
Multiple versions for one person
If the same person is exposed to two different versions in one round (for example, a shared device after an identity link), that person is excluded from the analysis and reported in data quality. When excluded people reach 1% of the total, the verdict becomes a data problem. See Data quality.
Browser-reported exposures
Viewport, pageview and manual exposures arrive at POST /xp/events from the browser. The server recomputes the visitor's assignment from the signed cookie and drops any exposure whose version does not match, counting those separately as mismatches. Browsers cannot report render exposures.
Prefetching
Next.js's default prefetch does not render the dynamic subtree inside <Suspense>, so it does not record exposures. Full prefetch (<Link prefetch={true}> or a full router.prefetch) of pages with render-policy blocks is unsupported: it would record an exposure before the visit.

