Skip to Content
Delmare Digital

Runtimes

Options for defineExperimentsProxyRuntime and defineExperimentsServerRuntime, and the manifest loaders.

The plugin uses two runtime objects. The proxy runtime is safe to import in proxy.ts: it has no Payload, React or Puck imports. The server runtime wraps it and adds a lazy Payload loader and user lookup. Create each once and import it wherever it is needed.

defineExperimentsProxyRuntime

From @delmaredigital/payload-experiments/runtime/proxy.

src/experiments/proxyRuntime.ts
export const proxyRuntime = defineExperimentsProxyRuntime({
  secret: [process.env.XP_SECRET!, process.env.XP_SECRET_PREVIOUS!],
  apiRoute: '/api',
  loadManifest: createPostgresManifestLoader({ pool }),
  cookie: { consent: (request) => request.cookies.get('consent')?.value === 'yes' },
})

Prop

Type

Manifest loaders

The manifest is the compiled, private configuration of every running, decided and archived test. It is rebuilt on each transition and cached by revision in the proxy.

createPostgresManifestLoader

createPostgresManifestLoader({ pool, schemaName? })

Reads the manifest straight from Postgres through a host-owned pg Pool, with no HTTP call back into your deployment. Point the pool at the same database as Payload, and set a finite connectionTimeoutMillis: the loader's refresh ceiling does not cancel pool work. Pass schemaName when Payload uses a custom Postgres schema.

createHttpManifestLoader

createHttpManifestLoader({ url, key, refreshTimeoutMs? })

Fetches the manifest from the plugin's GET /xp/manifest endpoint, for a proxy that cannot reach the database. key is sent as the x-xp-manifest-key header and must equal the hex HMAC-SHA256 of the string xp:manifest-key under the newest secret. refreshTimeoutMs defaults to 5000. Prefer the Postgres loader where you can: it avoids a request from the proxy into your own app.

defineExperimentsServerRuntime

From @delmaredigital/payload-experiments/runtime/server.

src/experiments/serverRuntime.ts
export const serverRuntime = defineExperimentsServerRuntime(proxyRuntime, {
  getPayload: async () => {
    const { getPayload } = await import('payload')
    const { default: config } = await import('@payload-config')
    return getPayload({ config })
  },
  getUser: () => getSessionUser(),
  attributesOf: (user) => ({ loggedIn: Boolean(user), staff: user?.role === 'staff' }),
})

Prop

Type

Attributes is Record<string, string | number | boolean>. Server attributes take precedence over the proxy's getUnit attributes. The plugin owns path.

Edit this page on GitHub

On this page