Skip to main content
Trevo records exactly two kinds of event. Getting the difference right is most of what separates a trustworthy experiment from a misleading one.
Both halves have to be right. A wrong denominator is harder to notice than a wrong numerator, and does just as much damage.

Exposure

Recorded when getVariant() resolves:
Deduplicated per identity and variant, so calling it repeatedly in a render loop doesn’t inflate anything.

Only where the user genuinely sees it

This is the trap. Exposure means saw, not was assigned. Resolve a variant in a component that renders off-screen, or on a page where the tested element is below the fold and never scrolled to, and you’ve added people to the denominator who never had the chance to convert. The effect is always the same: your measured lift shrinks toward zero, because you’ve diluted both arms with users who couldn’t have responded. A real winner can be buried this way. Two tools:
Use that pair when you need the variant early — to fetch data, to decide a layout — but the user won’t see the result until later.

Conversion

Nothing is captured automatically. There is no autocapture, no click tracking, no implicit pageviews. A conversion exists only where you write one:
Names are up to 500 characters; properties up to 8KB serialised.

Pick events that mean something

The best conversion events sit as close to real value as you can get while still happening often enough to measure.
  • purchase_completed — unambiguous, but rare, so it needs a lot of traffic
  • checkout_started — more frequent, and a decent proxy
  • button_clicked — plentiful and nearly meaningless on its own
A common shape is a frequent event as the decision metric and a rarer, more valuable one as a guardrail, so you can move fast without optimising for a click that leads nowhere.

Record them server-side where you can

Browser events are lost to ad blockers, closed tabs, and flaky networks. Anything your backend knows about — payments especially — is more reliably recorded there:
See Node or REST. This improves the numbers for your browser experiments too, because the denominator stays in the browser while the numerator becomes reliable.

How they meet

An exposure and a conversion are joined by identity. Trevo counts a conversion toward whichever variant that identity was exposed to. Which is why sending both userId and anonymousId from a backend matters: an event carrying only userId from a user whose exposure was recorded anonymously has nothing to join on, and that conversion is lost from the results. The SDKs send both automatically when they can; on REST, it’s your job.

Symptoms of getting this wrong