experiment. You can access it with the ACUL JS SDK or ACUL React SDK.
The experiment context is only delivered to screens where you have opted in. You opt in per screen by adding "experiment" to the context_configuration array for that screen.
To opt a screen in to receive experiment context, make a call to the PATCH /v2/prompts/{prompt}/screen/{screen}/rendering endpoint with the following in the request body:
Example
{prompt} with the prompt name (for example, login) and {screen} with the screen name (for example, login).
Experiment resolution and tenant log enrichment always run, regardless of whether a screen has opted in. The opt-in only controls whether
experiment properties are passed to your ACUL component. This is a data-minimization measure: don’t opt in screens that do not need experiment context.Access the experiment context with the ACUL SDKs
You can access the experiment context with version 1.9.0 or later of the ACUL JS SDK (@auth0/auth0-acul-js) or ACUL React SDK (@auth0/auth0-acul-react).
Use the SDK that matches how you build your ACUL screens:
- React SDK
- JS SDK
Use the
useExperiment() hook, which is available from every screen entry point of @auth0/auth0-acul-react.null when no experiment is active or the screen has not opted in.
The experiment context shape
The experiment context has the following shape:variationName and variationDescription to null when they aren’t defined, and set config to an empty object ({}) when the server doesn’t send a configuration.
The config property contains the merged configuration for the assigned variation. Experiment Center takes the feature flag’s baseline parameters and merges the assigned variation’s overrides on top. When the server sends a configuration, every parameter defined on the feature flag has a value in config.
For example, if your feature flag has a parameter button_label with a baseline value of "Sign in", and the assigned variation overrides it to "Continue", then config.button_label.value is "Continue".
For the control variation (no overrides), config.button_label.value is "Sign in".
Read a parameter value
Each entry inconfig is an object that wraps the resolved value, for example { value: "Continue" }. Read the resolved value from config[paramName].value:
.value rather than testing the entry itself. The wrapper object is always truthy, even when the resolved value is false:
config values are typed as unknown because parameter types are defined per experiment. In TypeScript, narrow the entry before you read it:
?.) throughout. The experiment property is null when no experiment is active.
Use isControl
TheisControl property is true when the user is in the control group (they received the baseline, no overrides applied). Use it when you need to track which users saw the unmodified experience, or when you want to skip optional processing for control users.
experiment exists before you check isControl. When no experiment is active, !experiment?.isControl evaluates to true, which runs the treatment branch for users who aren’t in an experiment.
For branching rendering, check the parameter value directly (config.my_param.value) rather than isControl.
Parameter-based checks are more readable and work correctly even when you change which variation is the statistical control in a future experiment.
Example: copy variant experiment
This example shows a feature flag with two variations that changes button copy. The control variation uses the standard label; the treatment variation uses an alternative. Feature flag parameters:button_label: "Sign in")
Treatment variation:
?? "Sign in" fallback handles the case where no experiment is active (in which case experiment is null and entry is undefined). If you prefer, you can use a separate null check:
Example: boolean feature rollout
This example uses a boolean parameter to conditionally show a new UI element.=== true check (rather than a truthy check) is intentional: it ensures the banner only shows when the parameter is explicitly true, not when experiment is null or config is empty.
Example: control and treatment in the JS SDK
This example uses the JS SDK to render the default experience for users with no experiment or in the control group, and the treatment experience only when the parameter resolves totrue.
renderDefaultLoginUI() and renderTreatmentLoginUI() are your own render functions. When an experiment has more than two variations, you can also branch on experiment.variationId.
Troubleshooting
Theexperiment property is null in three situations:
- No experiment is currently active for the tenant.
- The screen has not opted in via
context_configuration. - Experiment Center is not enabled on the tenant.
experiment is present but config is empty ({}), the server didn’t send a configuration for the variation. Read parameters with optional chaining and a default value so your screen still renders.
Always treat experiment as potentially null. The safest pattern:
experiment property is present. Code that relies on experiment being defined will throw errors when no experiment is running.