Plugin options
Every option of createExperimentsPlugin, with types, defaults and validation rules.
createExperimentsPlugin(options) from @delmaredigital/payload-experiments returns a Payload plugin. Options are validated at startup; an invalid option throws with a message naming it.
import { createExperimentsPlugin } from '@delmaredigital/payload-experiments'
createExperimentsPlugin({
runtime: serverRuntime,
access: { manage: canManageTests },
})Top level
Prop
Type
blocks, events and admin are inline shapes on the exported ExperimentsPluginOptions type; they are not separately exported named types. For example:
import type { ExperimentsPluginOptions } from '@delmaredigital/payload-experiments'
export type BlocksOptions = NonNullable<ExperimentsPluginOptions['blocks']>
export type BlocksCollection = BlocksOptions['collections'][number]
export type EventsOptions = NonNullable<ExperimentsPluginOptions['events']>
export type AdminOptions = NonNullable<ExperimentsPluginOptions['admin']>access
Each callback receives { req } and returns a boolean or a promise of one. Access is granted only for true.
Prop
Type
events
Prop
Type
dimensions values come only from attributes the server computes for the request (path, loggedIn, staff and your getUnit attributes), never from what a browser sends. Only strings (first 64 characters), numbers and booleans are kept. Names that identify a person, such as userId, email or ip, are refused at startup; whether an attribute you add identifies someone is your responsibility. For browser-reported exposures, path comes from the request's Referer. Results cannot yet be broken down by dimension; recording them now builds history for when they can.
pages
pages.collections registers collections for whole-page tests.
Prop
Type
blocks
blocks.collections registers Payload blocks fields for block tests without Puck. When blocks is set, collections must be a non-empty array; startup throws otherwise.
Prop
Type
puck
Prop
Type
admin
Prop
Type
PreviewPlacement (exported from the package root and /rsc) is { collection, id, title, published, slug? }. slug is the published row's string slug, including for a placement found in a newer draft, and is absent for unpublished documents. The older ({ collection, id }) => string form still works.
admin: {
previewUrl: ({ collection, slug }) =>
collection === 'pages' && slug !== undefined ? (slug === 'home' ? '/' : `/${slug}`) : null,
editorUrl: ({ collection, id, editor }) =>
editor === 'puck'
? `/admin/puck-editor/${encodeURIComponent(collection)}/${encodeURIComponent(String(id))}`
: `/admin/collections/${encodeURIComponent(collection)}/${encodeURIComponent(String(id))}`,
},Preview URLs are resolved on the server and only URL strings reach the browser. A null or undefined result, a non-string, an exception, a rejected promise or a timeout hides preview for that placement. Timed-out work cannot be cancelled and keeps its slot until it settles; if all 8 slots stay busy, further lookups in that check are skipped. Edit on page appears when an editor URL exists.
theme
theme: { accent: '#1f3a68' }accent accepts #rgb or #rrggbb; empty or undefined uses Payload's neutral palette. The plugin derives hover and pressed fills, a focus ring and an 8% tint. In dark mode it raises lightness when needed to reach 3:1 against the dark surface. Foreground text on the accent fill must reach 4.5:1 (WCAG 2.x) in each theme; a colour that fails is refused with its ratio. Status chips keep Payload's semantic colours. Pass the same accent to experimentsPuckEditor.
What the plugin adds
| Kind | Slugs |
|---|---|
| Collections | xp-experiments (Tests, with version history), xp-phases, xp-layers, xp-metrics (Goals), xp-events, xp-identities, xp-results-snapshots |
| Global | xp-state |
| Admin | A Tests nav group (All tests, Goals) for managers, dashboard cards, and the Tests views at /admin/experiments |
| Endpoints | Under /xp on Payload's API route. See REST endpoints |
Your app owns the migrations for these collections. A host nav group must not also be called "Tests"; a host collection with group: 'Tests' joins the plugin's group.

