GA4 export
ABTestly pushes a Google-specexperience_impression event to your site’s
dataLayer so you can cross-check experiment exposures (and run deeper
GA4-native analysis) inside your own GA4 property. The data lands in your
GA4 — ABTestly never sees it.
This is off by default. Enable it per site under Site → GA4 Integration.
ABTestly’s built-in results remain the primary analysis surface (clean
significance math, sample-ratio checks, per-variant lift with CIs). The GA4
export is for cross-validation and for richer GA4-native explorations (e.g.
conversion-by-variant for one experiment via the Segment recipe below, or
unconstrained multi-experiment SQL in BigQuery).
How it works
When a visitor is bucketed into a running experiment, the snippet pushes the Google official A/B-testing vendor event:exp_variant_string parameter follow Google’s official
spec for third-party
A/B-testing tools, which means our data plugs into standard GA4 A/B tooling
and Looker Studio templates designed for it. The ABT- prefix scopes the
dimension to ABTestly experiments.
The push is consent-gated: under Google Consent Mode v2 deferred mode, no
event fires until consent is granted. It also only fires for sites where the
GA4 toggle is on.
Event parameters
| Parameter | Description | Example |
|---|---|---|
exp_variant_string | Canonical combined dimension | ABT-7-1 |
experiment_id | Per-org experiment number (string) | 7 |
variant_id | Variant index, 0 = control (string) | 1 |
experiment_name | Human-readable experiment name (optional) | Change hero text |
Concurrent experiments
A visitor in N experiments fires Nexperience_impression events per page —
one per experiment. That is correct and required: it’s what the per-experiment
Segment recipe below relies on. There is no single “the variant” for a
visitor when they’re in multiple tests — that’s a property of how A/B
attribution works, not a tool limitation.
Setup (≈ 5 minutes)
The fastest path is the Google Tag Manager container template, which wires up everything except your Measurement ID.Import the GTM container
Download the template from Site → GA4 Integration → Download GTM
container. In Google Tag Manager: Admin → Import Container → choose a
workspace → Merge. It creates the four Data Layer Variables, the
experience_impression trigger, and a GA4 event tag.Point the tag at your GA4
Open the imported GA4 - ABTestly experience_impression tag and set its
Measurement ID to your
G-XXXXXXXXXX (or reference your existing GA4
configuration tag).Register the Custom Dimensions in GA4
In GA4: Admin → Custom definitions → Create custom dimension. Create
event-scoped dimensions matching the event parameter names:
exp_variant_string, experiment_id, variant_id, and (optional)
experiment_name.Without Google Tag Manager
If you tag GA4 directly (gtag.js) instead of GTM, listen for theexperience_impression event and forward the parameters to GA4:
Verifying it works
- Open your site with GA4’s DebugView active (or the GTM Preview pane).
- Trigger an experiment exposure (load a page where a running test targets you).
- You should see an
experience_impressionevent withexp_variant_string,experiment_id,variant_id, andexperiment_name.
GA4 numbers vs your ABTestly dashboard
If you compare theexperience_impression count in GA4 to the participant
count on your ABTestly dashboard, GA4’s number will usually be higher.
That’s expected — the two counts measure different things.
experience_impression(GA4) is an exposure event. It fires when a visitor sees an experiment on a qualifying page view. GA4 counts events.- Participants (ABTestly dashboard) are distinct visitors. Each visitor is counted once per experiment, no matter how many times they view the tested page.
experience_impression events but is one participant. This is by
design, not a discrepancy.
Compare variants in GA4 with rates, not counts. For a variant
comparison inside GA4, analyse conversion rate per variant —
conversions ÷ exposures (or conversions ÷ users, when using a User
segment) — segmented by
exp_variant_string. Rates are robust to the
events-vs-participants difference; raw impression counts are not. The
Segment recipe below sets this up correctly.Analyzing one experiment in GA4 (the Segment recipe)
Why you can’t just put
exp_variant_string as a dimension against a
conversion metric. GA4 event-scoped Custom Dimensions populate only on
events that carry the parameter. Your conversion events (signup, purchase,
…) don’t carry exp_variant_string, so a cross-tab “signup count by
variant” reads (not set). This is a GA4 mechanic, not a bug. The correct
approach — used by every other vendor that follows this spec — is Segments
in an Exploration.Recipe — one variant per segment, then compare
To break down a conversion event by variant for one experiment (say, display number 7), do this once per variant:Create one Segment per variant
Click Segments → + and choose User segment (preferred — survives
across sessions when User-ID or Google Signals is on) or Session
segment (single-session). Add an Include condition:Event
experience_impression with parameter exp_variant_string
exactly matches ABT-7-0 (the control).Save as “Exp 7 · Control”. Repeat for each variant — ABT-7-1,
ABT-7-2, etc.What this method gives you
- A conversion metric (signups, revenue, anything in GA4) attributed per variant for one experiment, using GA4’s session/user join — the same attribution GA4 uses for everything else.
- Works for any event the customer already tracks in GA4 — no need to forward the variant onto every conversion event.
Caveats — these are GA4 mechanics, not ABTestly bugs
- Not retroactive. Custom Dimensions only capture data from registration forward. Register them before you need to analyze.
- One experiment at a time. A visitor in N experiments carries N
exp_variant_stringvalues; there is no single “the variant” for a conversion event. Build one set of Segments per experiment. For across- experiment analysis at scale, use BigQuery. - Cross-device / cross-session attribution. GA4’s “user” is per-browser- cookie unless you have User-ID set or Google Signals on. Without one of those, a user who is exposed on desktop and converts on mobile counts as two users.
- 4-comparison limit in standard reports. Standard reports cap at four comparisons. Experiments with 5+ variants must use Explorations (Segment comparisons handle more).
(other)cardinality rollup. GA4 collapses high-cardinality dimension values into(other)in standard reports for properties with many running experiments. The Segment recipe avoids this (it filters to a specific string), which is another reason to prefer it over broad dimensional cross-tabs.
When you need more — BigQuery
For power users — many concurrent experiments, exact attribution across overlapping tests, or no dimension/audience caps — pipe GA4 to BigQuery and join impressions to conversions onuser_pseudo_id with the parameterized
SQL we ship. See GA4 BigQuery analysis.