tsk_live_…. It is publishable — it ships in your JavaScript bundle by design, and it can
read your experiment config and post events, and nothing else: it cannot read results,
change experiments, or touch workspace settings.
Where the key goes
Pasting the key intoinit() is fine for a first test. For anything deployed, put it in
an environment variable so rotating it never needs a code change:
Two rules keep this from going wrong:
- Match the key class to the surface. Browsers use the publishable
tsk_live_…key. Server SDKs use a server key (tsk_secret_…, created in Settings → SDK keys with platform Server), which must never reach a browser — the API rejects a secret key sent with anOriginheader for exactly that reason. - Redeploy after adding or rotating a key. Bundlers compile public env vars into your JavaScript at build time, and hosts like Vercel apply env changes to new deployments only. Until you redeploy, the live build keeps the old key and its events are rejected.
1. Install
Trevo. Pin the exact
version in production:
2. Initialise
Once, as early as your app boots:identify() when you know who the user is — usually right after login:
identify() later can move
someone from one variant to another. Call it as early as you can, and before rendering
anything you are testing.
3. Read a variant
getVariant() is synchronous and does no network call — assignment is a local hash of
the user’s identity and the experiment key. The same user always gets the same variant.
Keep your existing loading boundary visible until the first apply; reading once before
ready() can return control and never update when config arrives.
It returns 'control' for an experiment key it has never seen, so shipping this code
before the experiment exists in Trevo is safe.
Calling getVariant() also records an exposure — “this user saw this variant”. That
is the denominator for your results, so only call it where the user genuinely sees the
thing. To read an assignment without recording an exposure:
4. Record a conversion
Nothing is tracked automatically by the browser SDK (@trevosdk/react’s provider is the
one exception — it emits a page_view on mount). A conversion exists only where you write
one:
trevo.flush() exists if you want to force it.
5. Check it arrived
Open Data → Events in your workspace and refresh — the table doesn’t auto-update. Your event should appear within a few seconds. The Connect your app drawer (topbar → Connect SDK) polls live if you’d rather watch it arrive. If nothing shows up, see No events arriving.What to do next
- Using React?
install/reacthas a provider and a hook that handle initialisation for you. - On Next.js?
install/nextjsresolves variants on the server so the first paint is already correct — no flash of the control version. - Tracking conversions on a backend?
install/node,install/python, orinstall/ruby. Server-side events are immune to ad blockers and closed tabs, which improves the numbers for your browser experiments too. - Building a mobile app?
install/react-nativebuckets users identically to the web and is built for offline queues and app-store constraints. - Multiple variants?
defineExperiment()gives you a typed union and makes an unhandled variant a compile error. See Typed variants.