> ## 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.

# Product analytics

> Forward each experiment exposure to Segment, RudderStack, Amplitude, or Mixpanel so you can split any report by variant in the tools you already run.

ABTestly can forward each experiment **exposure** to the on-page product-analytics
SDKs you already load — Segment, RudderStack, Amplitude, and Mixpanel — as an
`experience_impression` event. Once the event is in your analytics tool, you can
break any chart, funnel, or retention curve down by variant using your own
conversion data. The event flows through the SDK already on the page; ABTestly
never sees it.

Each destination is **off by default**. Enable the ones you use per site under
**Site → Analytics integration**.

<Note>
  ABTestly's [built-in results](/results-methodology) remain the primary analysis
  surface (clean significance math, sample-ratio checks, per-variant lift with
  confidence intervals). Forwarding to product analytics is for slicing your
  existing reports by variant — not a replacement for the experiment readout.
</Note>

## How it works

When a consented visitor is bucketed into a running experiment, the snippet
calls `track` on whichever SDKs you've enabled:

```js theme={null}
window.analytics.track('experience_impression', {
  experiment_id: '7',                 // per-org experiment number (string)
  variant_id: '1',                    // variant index, 0 = control (string)
  experiment_name: 'Change hero text', // human-readable
  variant_name: 'Variant B',
});
```

The behavior is the same for every destination:

* **Consent-gated.** Nothing fires until the visitor has consented (the snippet
  gates on your [consent](/consent) signal, same as bucketing).
* **Exposure only.** ABTestly forwards the impression, not your conversions.
  Join it to your own events on `experiment_id` / `variant_id` inside your
  analytics tool.
* **Skipped when absent.** If the SDK isn't on the page, that destination is
  quietly skipped — no errors, no queued events.
* **Preview never sends.** Preview and QA sessions are suppressed, so your
  production numbers stay clean.
* **Never blocks the page.** Each call is wrapped so a throwing or misconfigured
  SDK can't affect your site.

## What gets sent

Every `experience_impression` event carries the same four properties. Register
them as custom properties in your destination if it needs an explicit schema.

| Property          | Example              | Meaning                       |
| ----------------- | -------------------- | ----------------------------- |
| `experiment_id`   | `"7"`                | Per-org experiment number     |
| `variant_id`      | `"1"`                | Variant index (`0` = control) |
| `experiment_name` | `"Change hero text"` | Human-readable name           |
| `variant_name`    | `"Variant B"`        | Human-readable variant        |

## Segment

ABTestly calls
`window.analytics.track('experience_impression', { … })`. Segment then routes
that event to every destination you've connected — your warehouse, Amplitude,
Mixpanel, and so on — so you only have to wire ABTestly once. It fires only if
the Segment SDK (`analytics.js`) is already on the page.

## RudderStack

Identical to Segment (RudderStack implements the same `analytics.js` API):
ABTestly calls
`window.rudderanalytics.track('experience_impression', { … })`, and RudderStack
routes the event to your connected destinations. Fires only if the RudderStack
SDK is on the page.

## Amplitude

ABTestly calls `window.amplitude.track('experience_impression', { … })`,
falling back to `logEvent()` on the legacy Amplitude SDK. The event lands in
Amplitude so you can split any chart, funnel, or retention analysis by
`variant_id`. Fires only if Amplitude is on the page.

## Mixpanel

ABTestly calls `window.mixpanel.track('experience_impression', { … })`. The
event lands in Mixpanel so you can break any report down by `variant_id`. Fires
only if Mixpanel is on the page.

## Analyzing by variant

Because ABTestly forwards the exposure and not your conversions, the analysis
pattern is the same everywhere: build a segment or breakdown per variant from
the `experience_impression` event (filter on `experiment_id`, group by
`variant_id`), then compare your existing conversion metric across those
variants. This is exposure-based attribution — a visitor counts toward a variant
from the moment they're bucketed.

<Note>
  Want ABTestly's own significance verdict, sample-ratio check, and per-variant
  confidence intervals instead of rebuilding them downstream? That's the
  [results dashboard](/results-methodology) — product-analytics forwarding is for
  reusing your existing reports, not re-deriving the experiment result.
</Note>
