Skip to main content
Two rules:
  1. Do not install ABTestly through GTM.
  2. Do fire GTM tags that depend on variant changes after ABTestly.

Why not through GTM

GTM defers script execution until after DOM parsing. By the time GTM fires, the page has painted. Loading ABTestly through GTM produces consistent flicker, 200 to 800 ms of original content visible before the variant swaps in. Install the ABTestly snippet directly in <head>, above your GTM snippet or below it (either order works, but ABTestly has to be a direct <script> tag, not a GTM tag). See Install the snippet.

Firing GTM tags that read variant changes

If a GTM tag depends on the variant that ABTestly applied, say, a custom dimension for the variant key, it needs to fire after the variant applies. Recommended pattern: listen for the experience_impression dataLayer event (see GA4 dataLayer) and fire your tag from a trigger scoped to that event.
  • GTM → Triggers → New → Custom Event.
  • Event name: experience_impression.
  • Any tag using that trigger fires once per exposure, with the variant fields available as {{ variant_key }}, {{ experiment_id }}, etc.

Order in <head>

ABTestly first because it needs to run before the browser paints. GTM after because it does its own async loading and does not need to be first. If your GTM setup uses Google Consent Mode, the two systems compose. ABTestly’s own consent gate (Consent) waits for window[consentKey] === 'granted'. Google Consent Mode manages GTM’s own tags. Both can be gated on the same consent flag.

Common questions

Can I have GTM install my consent-gated ABTestly snippet? No. same reason as “do not install through GTM”. Install the snippet directly and let its built-in deferred mode wait for consent. Can I push my own dataLayer events from variant code? Yes. Variant JS can call window.dataLayer.push({...}) freely. Just make sure the event is not something GTM will misinterpret as an ABTestly-internal event. Do I need a separate GTM container for ABTestly? No. Use your existing container and add tags that depend on ABTestly’s dataLayer events.