/Docs

onEvent Callback

window.avsb.onEvent is an optional callback you can assign to receive a notification every time the A vs B snippet fires an experiment event. It is the primary integration point for sending experiment data to a third-party analytics platform like Google Analytics, Segment, Mixpanel, or Amplitude — or to your own custom data pipeline.

How to set it

Assign a function to window.avsb.onEvent. That function will be called every time the snippet emits an event — bucketing a visitor into a variation, tracking a conversion, and so on.

Basic setup
javascript
1window.avsb.onEvent = function(event) {
2 console.log('A vs B event:', event);
3};

Setup order matters

To avoid missing early events (like the initial bucketing that happens as soon as the snippet loads), you should assign onEvent before the snippet finishes initializing. There are two reliable approaches:

  • Set it before the snippet tag — if your inline JavaScript runs before the snippet script, set window.avsb = window.avsb || {} then assign the callback. The snippet will detect and call the existing function once it loads.
  • Use projectJs— code in your project's projectJs field (JavaScript or TypeScript) runs during the snippet's initialization phase, before experiments are evaluated. Assigning onEvent there guarantees it is set in time for all events.
Set onEvent before the snippet tag (inline script)
javascript
1<!-- Place this script tag BEFORE the A vs B snippet tag -->
2<script>
3 window.avsb = window.avsb || {};
4 window.avsb.onEvent = function(event) {
5 // Your integration code here
6 };
7</script>
8
9<!-- Then the snippet tag -->
10<script id="avsb" src="https://cdn.avsb.cloud/snippet.js?id=YOUR_KEY"></script>

Event object shape

Every call to your onEvent callback receives a single event object with the following fields:

NameDescription
experiment_idstringRequired

The unique ID of the experiment that generated this event. Starts with exp_.

experiment_namestringRequired

The human-readable name of the experiment as set in the A vs B dashboard.

variation_idstringRequired

The unique ID of the variation the visitor is in. Starts with var_.

variation_namestringRequired

The human-readable name of the variation, such as "Control" or "Variant A".

event_namestringRequired

The type of event. Common values include "exposure" (visitor bucketed into a variation) and "conversion" (visitor triggered a metric conversion).

revenuenumberOptional

Present only on conversion events where a revenue value was passed to avsb.track.event(). Contains the monetary amount of the conversion.

Integration examples

Send to a custom analytics system
javascript
1window.avsb.onEvent = function(event) {
2 myAnalytics.track('ab_test', {
3 experiment: event.experiment_name,
4 variation: event.variation_name,
5 event: event.event_name
6 });
7};
TypeScript support in Project JS
If you write your Project JS in TypeScript, the onEvent callback parameter is fully typed. The editor provides autocomplete for all event fields (experiment_id, variation_name, event_name, etc.) without needing manual type annotations.
Send exposures to Google Analytics 4
javascript
1window.avsb.onEvent = function(event) {
2 if (event.event_name !== 'exposure') return; // only care about bucketing events
3
4 gtag('event', 'experiment_impression', {
5 experiment_id: event.experiment_id,
6 variant_id: event.variation_id
7 });
8};
Send to Segment
javascript
1window.avsb.onEvent = function(event) {
2 analytics.track('Experiment Viewed', {
3 experimentId: event.experiment_id,
4 experimentName: event.experiment_name,
5 variationId: event.variation_id,
6 variationName: event.variation_name,
7 eventName: event.event_name
8 });
9};
Send to Mixpanel with revenue
javascript
1window.avsb.onEvent = function(event) {
2 var props = {
3 experiment: event.experiment_name,
4 variation: event.variation_name
5 };
6
7 if (event.revenue !== undefined) {
8 props.revenue = event.revenue;
9 }
10
11 mixpanel.track('AB Test Event', props);
12};
Log all events for debugging
javascript
1window.avsb.onEvent = function(event) {
2 console.group('[A vs B] ' + event.event_name);
3 console.log('Experiment:', event.experiment_name, '(' + event.experiment_id + ')');
4 console.log('Variation:', event.variation_name, '(' + event.variation_id + ')');
5 if (event.revenue !== undefined) {
6 console.log('Revenue:', event.revenue);
7 }
8 console.groupEnd();
9};

Only one callback at a time

window.avsb.onEvent holds a single function reference. If you assign a second function to it, the first is replaced. If you need to run multiple integrations, compose them inside one function:

Running multiple integrations
javascript
1window.avsb.onEvent = function(event) {
2 // Segment integration
3 analytics.track('Experiment Event', {
4 experiment: event.experiment_name,
5 variation: event.variation_name
6 });
7
8 // Mixpanel integration
9 mixpanel.track('AB Test', {
10 experiment: event.experiment_name,
11 variation: event.variation_name
12 });
13
14 // Custom logging
15 console.log('[AvsB]', event.event_name, event.experiment_name);
16};
Filter by event_name to avoid double counting
The callback fires for every event, including bucketing exposures and conversions. If you are sending data to an analytics platform, you may want to filter by event.event_name to send only exposure events, only conversion events, or both — depending on what your analytics platform expects. Sending all events without filtering can lead to unexpected data in your analytics dashboards.
Do not perform slow operations inside onEvent
The onEvent callback is called synchronously during snippet event processing. Avoid performing blocking operations inside it — such as synchronous network requests or heavy DOM manipulation. Third-party analytics SDKs like gtag, analytics.track(), and mixpanel.track() are designed to be non-blocking and are safe to call here.