experience_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
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.1
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.2
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).3
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.4
Publish and enable
Publish the GTM container, then turn on the Export to GA4 toggle in
ABTestly.
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:1
Open Explore → Free form
In GA4: Explore → + → Free form.
2
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.3
Build the comparison
Drop the segments into the Segment comparisons slot. Drop your
conversion event count (or revenue) into Values. The table now shows
that metric per variant — the right way.
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.
Importing GA4 goals
Re-using an existing GA4 conversion as an experiment goal is on the roadmap but not yet available. If you need it, let us know at support@abtestly.com and we’ll prioritise it.Start testing
Create a free ABTestly account
The free tier covers 3,000 monthly tracked users and one active experiment, no credit card. Edge-served snippet, with sample size and confidence intervals shown on every result.