Skip to content

A/B Test Tracking

When you run an A/B test using an external tool (VWO, Optimizely, Kameleoon, AB Tasty) or a feature-flag platform (LaunchDarkly, Statsig, GrowthBook), you need to send the test assignment to GA4 so you can split your conversion data by variant. This recipe covers the dataLayer integration for any testing tool, plus how to model the data correctly in GA4.

GA4 has no reserved event name or parameter for experiments. Every convention below is something you define in your container and register in GA4 Admin. We recommend the following canonical shape across all testing tools:

FieldTypePurpose
experiment_impressionEvent nameFires once per user per session when the variant is applied
experiment_idEvent parameter (string)Stable identifier for the test (e.g. checkout-copy-v2)
experiment_nameEvent parameter (string, optional)Human-readable name
variant_idEvent parameter (string)The assigned variant (control, A, B)
variant_nameEvent parameter (string, optional)Human-readable variant name
active_experimentUser property{experiment_id}_{variant_id} — rides on every subsequent event

The user property is the load-bearing part. Event parameters only exist on the impression event. The user property rides on every downstream event (purchase, sign_up, custom conversions), which is what makes test-to-conversion attribution work. See Forwarding Variant to Conversions for why that matters and how to do it right.

Register all four event parameters and the user property in GA4 Admin → Custom Definitions before launching. Unregistered parameters don’t appear in reports.

Every A/B testing tool assigns the user to a variant before the page renders. The right place to push the variant assignment to the dataLayer is immediately after your testing tool determines the assignment — usually in a callback or immediately after the tool’s script initialises.

dataLayer.push() experiment_impression

Push this when the test variant is assigned, before the variant renders.

// Generic pattern — adapt to your testing tool's callback
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
event: 'experiment_impression',
experiment_id: 'checkout-button-color-v2',
experiment_name: 'Checkout Button Color Test',
variant_id: 'B',
variant_name: 'Green Button'
});
// VWO onActivate callback
VWO.event('vwo-loaded', function(data) {
var campaignData = data.campaignData;
for (var id in campaignData) {
if (campaignData.hasOwnProperty(id)) {
var campaign = campaignData[id];
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
event: 'experiment_impression',
experiment_id: 'vwo_' + id,
experiment_name: campaign.name,
variant_id: String(campaign.variationId),
variant_name: campaign.variationName
});
}
}
});
  1. Create a Custom Event Trigger

    • Trigger type: Custom Event
    • Event name: experiment_impression
  2. Create Data Layer Variables

    • DLV - experiment_idexperiment_id
    • DLV - experiment_nameexperiment_name
    • DLV - variant_idvariant_id
    • DLV - variant_namevariant_name
  3. Create a GA4 Event Tag

    • Event name: experiment_impression
    • Parameters:
      • experiment_id{{DLV - experiment_id}}
      • experiment_name{{DLV - experiment_name}}
      • variant_id{{DLV - variant_id}}
      • variant_name{{DLV - variant_name}}
    • Trigger: the Custom Event trigger
  4. Register custom dimensions in GA4

    Go to GA4 → Admin → Custom Definitions → Custom Dimensions:

    • experiment_id → Event scope
    • experiment_name → Event scope
    • variant_id → Event scope
    • variant_name → Event scope
  5. Set as a User Property for session-level persistence

    If you want to filter conversion events by variant (not just filter experiment impression events), set the variant as a user property:

    In your GA4 event tag, add a User Property:

    • Name: active_experiment
    • Value: {{DLV - experiment_id}}_{{DLV - variant_id}}

    Register this in GA4 → Admin → Custom Definitions → User Properties as well.

Tag Configuration

GA4 - experiment_impression

Type
Google Analytics: GA4 Event
Trigger
Custom Event - experiment_impression
Variables
DLV - experiment_idDLV - variant_idDLV - variant_name

Once the user property is set, you can split any GA4 report by experiment variant:

  1. Go to Explore → Blank Exploration
  2. Add dimension: User > active_experiment
  3. Add metrics: Conversions, Purchase revenue, Engaged sessions per user
  4. Filter to only users who were exposed to the test

For statistical significance, export the data to Google Sheets or BigQuery and run a chi-squared test or Bayesian analysis. GA4 does not have built-in statistical significance testing.

  1. Open GTM Preview and navigate to the page with the A/B test
  2. Trigger the variant assignment (your testing tool should do this on page load)
  3. Verify experiment_impression fires in the Summary pane
  4. Check variant_id and experiment_id are correct in the Variables tab
  5. In GA4 DebugView, verify the event appears with the variant parameters

Testing tool fires after GTM. If the testing tool loads asynchronously after GTM, the dataLayer push may arrive before the testing tool has determined the variant. Use the testing tool’s own callback or activation hook, not a hardcoded delay.

Anti-flicker snippet timing. Many testing tools hide the <body> content with CSS until the variant is applied, to prevent flash of original content. The dataLayer push timing should match the variant application, not the page load.

Multiple experiments running simultaneously. If you run multiple experiments at once, push separate experiment_impression events for each. Do not try to concatenate them into a single event.