Google Tag Manager
Google Tag Manager works with A vs B in three separate ways, and you can use any combination of them:
- Send experiment events into the dataLayer, so your own GTM tags can react to them.
- Deploy the A vs B snippet as a Custom HTML tag instead of editing your site.
- Record purchases from the GA4
purchaseevent your dataLayer already pushes.
Send experiment events into the dataLayer
Turn on the Google Tag Manager card in Project Settings > Integrations. It is off until you turn it on, so nothing is ever pushed into your dataLayer without you asking.
- The on/off switch, top right of the card.
- The dataLayer event name, the trigger name your GTM tags listen for. Defaults to
avsb_experiment. - The Also send checklist for conversions, purchases, and recommendation events.
A variation is one specific version being tested: the control, or one of the challengers. Once the card is on, this is what a visitor being shown one looks like:
window.dataLayer = window.dataLayer || [];window.dataLayer.push({ event: 'avsb_experiment', avsb_experiment_id: '482', avsb_experiment_name: 'Homepage hero', avsb_variation_id: '1913', avsb_variation_name: 'Variant B', avsb_event_name: 'avsb_experiment_viewed', avsb_event_id: '3f9a2b1c-7d4e-4a58-9c02-5e6d1f8b3a47'});Two names matter here and they do different jobs:
eventis what your GTM trigger listens for. It is the same for every A vs B event, so one trigger catches them all. Change it in dataLayer event name on the card.avsb_event_namesays which kind of event this was. Use it in a trigger condition when you want to react to only one kind.
| Kind | Default avsb_event_name | Extra keys |
|---|---|---|
| Experiment view | avsb_experiment_viewed | none |
| Conversion | avsb_goal | avsb_goal_key, plus avsb_revenue or avsb_value when you sent one |
| Purchase | avsb_purchase | avsb_revenue, avsb_currency, avsb_transaction_id |
| Recommendation seen | avsb_rec_impression | the recommendation details |
| Recommendation clicked | avsb_rec_click | the recommendation details |
| Test event | avsb_test_event | avsb_test: true |
Experiment views are always sent. Conversions, purchases, and recommendation events are only sent if you tick them under Also send. Empty values are left out rather than pushed as nulls.
Set up the trigger and variables
Create the trigger
Go to Triggers > New, choose Custom Event, and set the event name to avsb_experiment (or whatever you set on the card).
Create data layer variables
Go to Variables > New > Data Layer Variable and add one for each key you want: avsb_experiment_name, avsb_variation_name, avsb_event_name, and any others from the table.
Use them in a tag
Add those variables to whichever tag you want to receive experiment data, and set its trigger to the one you just made.
Publish
Submit and publish your GTM container.
Check it works
On the Integrations tab, use Send a test event. It opens your site in a new tab and sends one clearly labelled test event, avsb_test_event, to every tool you have switched on. Open GTM's Preview mode first and you will see the push arrive with avsb_test: true on it.
Your project needs at least one live experiment for this to work, since the test event is sent against the first one.
If the only thing you want is experiment data in Google Analytics, turn on the Google Analytics 4 card instead. It talks to the Google tag directly and needs no tags, triggers, or variables. Use this card when you want experiment data in something else that GTM already feeds.
Install the snippet as a Custom HTML tag
Your snippet comes from Project Settings > Snippet in the A vs B dashboard. It is two tags, and you need both:
<script>window.avsb=window.avsb||{};window.avsb.q=window.avsb.q||[];window.avsb.ready=window.avsb.ready||function(f){window.avsb.q.push(f)};window.avsb.on=window.avsb.on||function(n,f){var t=['on',n,f];window.avsb.q.push(t);return function(){t[0]=null}};window.avsb.consent=window.avsb.consent||{set:function(s){window.avsb.q.push(['consent.set',s])},get:function(){return{}}};window.avsb.track=window.avsb.track||{};['event','segment','purchase','cart'].forEach(function(m){window.avsb.track[m]=window.avsb.track[m]||function(a,b){window.avsb.q.push(['track.'+m,a,b])}});(function(){window.avsb._t0=Date.now();window.avsb._df=fetch('https://cdn.avsb.cloud/YOUR_SNIPPET_KEY/datafile.json').catch(function(){});var d=document,e=d.documentElement,s=d.currentScript,a=s&&s.getAttribute('data-avsb-timeout'),t=a==null?3000:+a;if(!(t>0)||window.avsb.version)return;e.style.opacity='0';e.style.pointerEvents='none';window.avsb._t=setTimeout(function(){e.style.removeProperty('opacity');e.style.removeProperty('pointer-events')},t)})();</script><script src="https://cdn.avsb.cloud/snippet.js?id=YOUR_SNIPPET_KEY" data-avsb="YOUR_SNIPPET_KEY" async></script>Paste both tags. The first one makes avsb.ready(...), avsb.on(...) and avsb.consent.set(...) calls safe whatever the load order, and the second one loads the snippet.
Loading the snippet through GTM means it fires after GTM itself loads. For experiments that change content above the fold, that delay raises the chance of visible flicker. If you can edit your site's HTML, paste both snippet tags directly into the head and use GTM only for the rest of your tags.
Create a new tag
In your GTM workspace, go to Tags > New and name it A vs B Snippet.
Choose Custom HTML
Click Tag Configuration and select Custom HTML. Paste both snippet tags into the HTML box.
Trigger on All Pages
Click Triggering and select All Pages.
Set priority
In Advanced Settings, set Tag firing priority to a high number (for example 100) so the snippet fires before your other tags.
Publish
Click Submit, then Publish. Verify in Project Settings > Snippet in A vs B: the status turns green once the snippet has been detected.
For Preview mode testing and single page app caveats, see the full Google Tag Manager install guide.
Record purchases from the dataLayer
If your site already pushes the standard GA4 purchase event, which most GTM commerce setups do, A vs B can read those pushes instead of you adding another tag. Turn it on with the Read purchases from your data layer switch under Project settings → Configuration → Advanced settings, or by setting autoCollectDataLayer to true through the Projects API. Once it is on, the snippet watches window.dataLayer and turns purchase pushes into A vs B purchase records, with no extra GTM tag.
The Google Analytics 4 / dataLayer switch on your Product catalog page is a different setting. That one reuses your analytics to collect product data (view_item, add_to_cart, view_item_list), and it does not affect purchases.
This is the shape it picks up:
window.dataLayer = window.dataLayer || [];window.dataLayer.push({ event: 'purchase', ecommerce: { transaction_id: 'ORDER-8842', value: 49.99, currency: 'USD', items: [ { item_id: 'SKU-001', item_name: 'Widget', quantity: 1, price: 49.99 } ] }});The legacy Universal Analytics shape (ecommerce.purchase.actionField) is recognised too. Purchases pushed to the dataLayer before the snippet loads are scanned on init, so tag ordering does not cost you orders. Duplicate transaction_id values on the same page view are suppressed, and orders are deduplicated by ID server side as well.
Purchases A vs B picked up from your dataLayer are recorded, but they are never pushed back into the dataLayer as an A vs B purchase event, even with the card and the purchases opt-in both on. That would double count the order in any tag listening to both.
Alternative: a purchase tag
If your dataLayer does not carry a GA4 purchase event, or you are not using the product catalog, fire avsb.track.purchase from a second Custom HTML tag triggered on your purchase or confirmation event, reading values from your own dataLayer variables:
<script> if (window.avsb && window.avsb.track) { window.avsb.track.purchase({ orderId: {{DLV - order_id}}, total: {{DLV - order_total}}, currency: {{DLV - order_currency}} }); }</script>orderId and total (a decimal) are required; currency is optional and defaults to your project's configured currency.
Verify
Place a test order, then open Commerce > Orders in the A vs B dashboard (see the orders and attribution guide) to confirm the order arrived and was attributed to an experiment view.