@traffical/react provides a context provider and hooks for resolving parameters and tracking events in React apps. It wraps @traffical/js-client, so everything the browser client supports works here too.
Installation
Setup
Wrap your app withTrafficalProvider:
traffical_sk_..., scopes sdk:read+sdk:write) in browser code — it is browser-safe.
The useTraffical hook
Use useTraffical in any component to resolve parameters and track events:
Hook options
| Option | Type | Description |
|---|---|---|
defaults | Record<string, ParameterValue> | Default values for the parameters this component reads. Required. |
context | Context | Optional extra context merged with provider context. |
tracking | "full" | "decision" | "none" | Tracking mode (see below). Default "full". |
Hook return value
| Field | Type | Description |
|---|---|---|
params | Record<string, ParameterValue> | Resolved parameter values |
decision | DecisionResult | null | Full decision record (decisionId, layer assignments) |
ready | boolean | true once the bundle has loaded at least once |
error | Error | null | Any non-fatal error from the last refresh |
track | (event, options?) => void | Track an event |
trackExposure | () => void | Manually emit an exposure (for "decision" mode) |
flushEvents | () => Promise<void> | Force flush of pending events |
Tracking modes
"decision" is useful when the variant is below the fold — you want to record the decision but only count exposure once the user actually sees the change.
Setting context
Pass user context through the provider; it flows to all hooks:contextFn inside config — a function called on each resolution. When the values it returns change (e.g. after login), hooks re-resolve with the new values. To customize the unit key, pass unitKeyFn inside config as well.
Anonymous users and identify
The React SDK inherits the browser client’s stable-ID handling. Before the user logs in, the SDK uses an auto-generated stable ID. After login:
SSR (Next.js, RSC)
For Next.js (App Router or Pages), fetch the bundle on the server and pass it aslocalConfig:
Standalone tracking
If you only need to track an event, useuseTrafficalTrack:
Direct client access
If you need to do something the hooks don’t expose, get the underlying client:Provider options
TrafficalProvider takes exactly two props: config and children. Everything else is a field of config (TrafficalProviderConfig):
config field | Type | Default | Description |
|---|---|---|---|
orgId | string | required | Organization ID |
projectId | string | required | Project ID |
env | string | required | Environment name |
apiKey | string | required | SDK key (traffical_sk_..., scopes sdk:read+sdk:write) — browser-safe |
baseUrl | string | https://sdk.traffical.io | SDK API base URL |
localConfig | ConfigBundle | — | Embedded bundle for cold-start / SSR hydration |
refreshIntervalMs | number | 60000 | Bundle refresh interval |
unitKeyFn | () => string | — | Custom unit-key resolution |
contextFn | () => Context | — | Dynamic context — called on every resolution |
trackDecisions | boolean | true | Emit decision events alongside exposures |
plugins | Plugin[] | — | SDK plugins |
config.
Next steps
SSR patterns
No FOOC, hydration with the same bundle.
Canonical experiments
Patterns for web UI and SSR tests.