> ## Documentation Index
> Fetch the complete documentation index at: https://docs.abtestly.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Analytics adapters

> Push ABTestly exposures to your existing analytics tool. GA4, Segment, RudderStack, Amplitude, Mixpanel, turn on the ones you use, ignore the rest.

**Site → Settings → Analytics.** Publish-gated. Each toggle
republishes the snippet so the change reaches the browser within about
sixty seconds.

<Frame caption="Analytics adapters, toggles for GA4, Segment, RudderStack, Amplitude, Mixpanel.">
  <img src="https://mintcdn.com/abtestly/pnpJFDTFa50Ks6SL/images/settings-analytics.png?fit=max&auto=format&n=pnpJFDTFa50Ks6SL&q=85&s=e3e80b518d645fbd1c7ebceffef5755b" alt="Settings: Analytics adapters" width="2400" height="1141" data-path="images/settings-analytics.png" />
</Frame>

## What each adapter does

When enabled, the snippet calls into the on-page SDK for the tool. The
call happens at exposure time, once per (visitor, experiment,
pageview).

### GA4

Pushes an `experience_impression` event into `window.dataLayer`. Fields:

* `experiment_id`, UUID
* `experiment_name`, human name
* `experiment_number`, short numeric id
* `variant_key`, short key (`control`, `variant-1`, …)
* `exp_variant_string`, `id.variant_key` concatenated, the format GA4
  uses for experiment slicing.

Read that field in a GA4 exploration to split any conversion by
variant. See [GA4 dataLayer](/integrations/ga4-datalayer) for the
exact shape and how to slice reports.

### Segment

Calls `window.analytics.track('Experiment Viewed', { … })` with
the same field set.

### RudderStack

Calls `window.rudderanalytics.track('Experiment Viewed', { … })`.

### Amplitude

Calls `window.amplitude.track(...)` if the modern SDK is present, or
falls back to `window.amplitude.logEvent(...)` for the legacy SDK.

### Mixpanel

Calls `window.mixpanel.track(...)`.

## Requirements

Each adapter requires the corresponding SDK to be on the page **before**
the snippet fires exposures. In practice that means loading the SDK in
`<head>` above or below the ABTestly snippet, either order works, as
long as the SDK is defined by the time an experiment first exposes.

If the SDK is missing when the exposure fires, the adapter no-ops
silently and reports a first-occurrence-per-session
[`/err`](/developer/errors-and-telemetry) event. Your dashboard's
Snippet health panel will surface it.

## Preview mode is quiet

Adapter calls are suppressed when the visitor is in
[preview mode](/preview/preview-modal). You do not want a QA preview
polluting your live analytics.

## Consent

Adapters compose with the consent gate. If consent is set to
**deferred** and the visitor has not granted, adapter calls do not
fire, the snippet is not running yet. Once consent is granted the
snippet runs and adapters fire.

## Turning them all off

That is fine. ABTestly's own results page reads from the ledger, not
from your analytics tool. Adapters exist because you probably want the
data in the tool your team already uses, not because ABTestly needs
them.

## What ends up in your analytics

**One event per (visitor, experiment, pageview).** Not one per goal.
your existing conversion tracking already fires goals; the exposure
event is what lets you slice those existing conversions by variant.

Downstream, that means:

* In GA4, add `exp_variant_string` as a custom dimension to any
  standard conversion report.
* In Segment/Rudder, filter or group events by the `experiment_id`
  or `variant_key` property.
* In Amplitude, use the event's property as a chart segmentation.
* In Mixpanel, same, segment your conversion events by
  `experiment_id` / `variant_key`.

## The full field set on every adapter

Every call includes:

* `experiment_id`
* `experiment_name`
* `experiment_number`
* `variant_key`
* `variant_name`
* `exp_variant_string`
* `abtestly_visitor_id`, a hash, not your visitor's id.

If you need any additional fields in the payload, tell us, most
adapter changes are five-line changes to the snippet.
