@trevosdk/browser assigns variants and records events in the browser. It never touches
the DOM — your own code branches on the variant it returns.
Under 10kb gzipped, no dependencies. This is the plain JavaScript SDK — on React use
@trevosdk/react, which wraps it in a provider and a hook.
Install
Without a bundler
The CDN build exposes a global calledTrevo. Pin the exact version in production —
the floating channels change under you with no deploy on your side.
Use
v0 or latest for prototyping only.
Initialise
NEXT_PUBLIC_, VITE_, PUBLIC_. Fail explicitly when
it is missing; passing an empty string makes setup fail later and is much harder to diagnose.
The key is publishable (tsk_live_…) and belongs in your client bundle. Server keys
(tsk_secret_…) are rejected from browsers.
Where the key goes lists the variable
for each stack — and why a key change needs a redeploy.
init() is re-entrant — calling it again reconfigures rather than duplicating.
Options
Identify the user
trevo_id cookie (1 year, SameSite=Lax) — the cookie is what lets your backend and SSR
bucket the same visitor. After it, they
are bucketed on your user id — which means identify() can change a user’s variant.
Call it as early as you can, and before rendering anything under test.
Anonymous ids are per browser, so the same person on a phone and a laptop is two
participants until they sign in.
On logout:
Read a variant
'control', so this is safe to ship before the
experiment exists.
The first call records an exposure, deduplicated per identity and variant within a
10-minute window. Calls made before config has loaded return control and record nothing,
so a page that reads only once, before ready(), never counts that visitor. The SDK warns in
the console and reports a read_before_ready SDK error for it, once per experiment, and the
experiment’s page in the dashboard shows how many visitors were missed. Read inside
onChange() and after ready(), as above, and it never fires. To read without recording an
exposure:
Typed variants
defineExperiment() returns a typed union and turns an unhandled variant into a compile
error — so a variant added in Trevo that your code does not handle fails the build instead
of silently falling through:
Track conversions
trevo.flush() forces a send if you need one.
Limits: event names up to 500 characters using A–Z a–z 0–9 _ . - $ only (anything else
is dropped with a console warning); properties up to 8KB serialised.
Waiting for config
On a first visit the SDK has no cached config, sogetVariant() returns 'control' until
the first fetch lands. Returning visitors read from a warm cache and are correct
immediately.
ready() also resolves after the first fetch fails. Keep the onChange() subscription shown
above so a later successful poll updates the view instead of pinning that visitor to control.
To avoid the flash of control on a first visit entirely, either resolve variants on the
server (Next.js) or use the anti-flicker snippet below.
Anti-flicker
Hides the page until variants are resolved, with a safety timeout so a blocked or failed SDK can never leave your page blank:<script> in <head>, before anything renders. It reveals automatically
after 1 second by default:
manualReveal: true, call trevo.reveal() once you have committed the variant.
Server-side bootstrapping is better where you can do it — nothing is hidden and there is
no timeout to tune.
Consent and opt-out
reset() leaves the SDK working: the visitor becomes a new anonymous participant,
so post-logout page views, variant reads and conversions are still recorded.
optOut() is the opposite — queued events are discarded rather than delivered, and
no new anonymous id is minted. Both are idempotent and safe to call before init().