Server helpers
Every export of the /rsc entry point, for Server Components, route handlers and host hooks.
Import from @delmaredigital/payload-experiments/rsc. This entry point is safe in route handlers and the Payload config; the admin server views live separately on /admin/rsc.
Reading assignments
getAssignments
getAssignments(serverRuntime, { user? }?): Promise<Assignments>Reads and verifies the signed request context, resolves users the proxy deferred (sessionUnknown), and recomputes stale or missing assignments from the signed cookie and the manifest. Memoised per request. It reads dynamic Next.js headers: call it inside <Suspense> under Cache Components, and never inside 'use cache'.
Assignments.bySlug maps each test's short name to { slug, experimentId, arm, phase, exposable, policy, source }. staff, bot and preview say why nothing would be counted.
resolveExperimentData
resolveExperimentData(puckData, assignments): { data, rendered }Removes unselected Puck versions and returns the data to render plus rendered, the block exposures with the render policy actually present.
resolveExperimentBlocks
resolveExperimentBlocks(blocks, assignments, { blockSlug? }?): { blocks, rendered, groups }The same for a Payload blocks field. See Payload blocks.
getFlagPoint
getFlagPoint(serverRuntime, id, { user? }?): Promise<FlagPointResult & { expose(renderedArm): Promise<void> }>Returns arm, params, source (experiment or default), optional experiment and experimentId, and expose. See Flag points.
toClientAssignments
toClientAssignments(assignments, { pathname, apiRoute?, flagPoints?, experiments? }): ClientAssignmentsThe value for ExperimentsProvider, with no visitor identifiers. See Client counting.
Recording
recordExposures
recordExposures(serverRuntime, rendered, assignments): Promise<void>Records render-policy exposures. Pass the rendered list from a resolver, never the whole assignment map, and schedule it with after() only when you deliver that content. Capture request values before after().
trackConversion
trackConversion(serverRuntime, { eventName, value?, idempotencyKey, userId?, headers? }): Promise<void>Records a server conversion for an event source (value defaults to 1). See Goals and conversions.
linkIdentity
linkIdentity(serverRuntime, { headers, userId, verified }): Promise<'linked' | 'verified' | 'skipped' | 'failed'>Links the browser to a user. Never throws. See Signed-in users.
eraseUser
eraseUser(payload, { userId }): Promise<{ identities: number; events: number }>Deletes a user's identity links and associated events in one transaction.
Results
runResults
runResults(payload, { budgetMs?, experimentId?, sweep? }?): Promise<{
ran: number
skipped: number
failed: number
swept: number
processedIds: (string | number)[]
budgetExhausted: boolean
unavailableMetrics?: {
experimentId: string | number
phase: number
metricId: string | number
reason: MetricUnavailableReason
}[]
sweepAttempted?: boolean
}>Computes results and returns an inline object; there is no exported RunResultsSummary. To name the return type in your app, use Awaited<ReturnType<typeof runResults>>. See Results runner.
SEO
experimentMetadata
experimentMetadata(serverRuntime, path): Promise<Pick<Metadata, 'robots' | 'alternates'>>Metadata to merge after your own in a dynamic generateMetadata. See Whole pages.
experimentSitemapFilter
experimentSitemapFilter(path, manifest): booleanSynchronous sitemap filter. Keep paths where it returns true.
pageKindSeoContract
pageKindSeoContract({ secret, original, versions, state, winner? }): { manifest, rows }Builds fixtures for testing your SEO wiring. See Whole pages.
Content-change tracking
recordContentChange and captureContentBaseline
recordContentChange({ doc, previousDoc, req, collection }): Promise<void>
captureContentBaseline // a Payload beforeChange hookFor host collections tagged with createArmSelectField, call recordContentChange from afterChange to add a content-change marker to the results chart. For collections with drafts, also add captureContentBaseline to beforeChange so the previously published content can be compared; for collections without drafts it is optional and gives an exact raw comparison (otherwise relationships are compared by id). Pass the hook's transaction req.
Markers compare published content: drafts and autosaves add none, and collections without drafts record on save. Neither function ever throws into your save; a failure is logged and the save proceeds. Registered Puck, blocks and pages collections get these hooks automatically.
Testing helpers
compileManifest
compileManifest(inputs, revision, { attributeKeys?, onInvalid? }?): ManifestBuilds a manifest from plain inputs with the same compile rules, for host tests, without database access. Pass the same attributeKeys as the plugin. Its input shape may change in a pre-1.0 minor release.
Types
/rsc also exports the Manifest, ManifestExperiment, PreviewPlacement, MetricUnavailableReason, ContentReportReason, block and SEO-contract types.

