April 23, 2026
A/B Testing with Google Tag Manager
Set up an A/B test in Google Tag Manager step by step — the cookie split code, the GA4 custom dimension nobody registers, and the flicker trade-off.
Since Google Optimize shut down in September 2023, marketers have scrambled for free alternatives. One approach that keeps surfacing: using Google Tag Manager (GTM) to run A/B tests directly. It works, it's free, and you probably already have GTM installed. But it comes with trade-offs most guides gloss over.
This guide walks you through how GTM-based A/B testing actually works, when it makes sense, and when you're better off using a purpose-built tool like PageDuel.
How GTM A/B Testing Works
The basic idea is simple: use GTM's Custom HTML tags and JavaScript to randomly assign visitors to a control or variant group, store that assignment in a cookie, and then modify the page accordingly. Here's the standard approach:
- Create a random assignment cookie. Use a Custom HTML tag or the community Cookie Creator template to generate a random number (e.g., 0–99). Values 0–49 go to the control group, 50–99 go to the variant.
- Read the cookie on subsequent visits. Set up a 1st-Party Cookie variable in GTM to read the assignment value so returning visitors always see the same version.
- Modify the page with JavaScript. Fire a second Custom HTML tag that checks the cookie value and applies DOM changes — swapping a headline, changing a CTA button color, or hiding an element.
- Push events to GA4. Use
dataLayer.push()to send a custom event (likeab_split_test) with dimensions for the experiment name and variant. Then track conversions in GA4 to compare performance.
Tools like the free GTM Testing library from ABTestGuide.com streamline this process with a lightweight snippet that handles randomization and cookie management. Simo Ahava's popular GTM split test guide takes a similar cookie-and-redirect approach for URL-level tests.
The Actual Setup, Step by Step
Most GTM testing tutorials describe the idea and stop at the description. Here is the working version: two tags, one variable, and the reporting step almost everyone forgets.
1. Assign the visitor and remember the assignment
Create a Custom HTML tag and set its trigger to Initialization — All Pages, not the ordinary All Pages trigger. Initialization tags fire before the regular page-view tags, which buys you a few milliseconds against flicker. Simo Ahava's original GTM split test used a two-year cookie for the same reason: the visitor has to keep seeing the same variant on every later visit, or you are measuring noise.
<script>
(function () {
var NAME = 'gtm_exp_headline';
var parts = ('; ' + document.cookie).split('; ' + NAME + '=');
var stored = parts.length === 2 ? parts.pop().split(';').shift() : null;
var variant = stored || (Math.random() < 0.5 ? 'control' : 'variant');
if (!stored) {
document.cookie = NAME + '=' + variant +
';path=/;max-age=' + (60 * 60 * 24 * 730) + ';SameSite=Lax';
}
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
event: 'ab_assign',
ab_test: NAME,
ab_variant: variant
});
})();
</script>
2. Apply the variant
Add a 1st-Party Cookie variable in GTM pointing at gtm_exp_headline, then fire a second Custom HTML tag that only does the DOM change. Keep the assignment and the application in separate tags — when a test misbehaves you want to be able to pause the change without losing everyone's bucket.
<script>
if ({{Cookie - gtm_exp_headline}} === 'variant') {
var el = document.querySelector('[data-test="hero-headline"]');
if (el) el.textContent = 'Ship your first experiment today';
}
</script>
Target a dedicated data- attribute rather than a CSS class. Classes get renamed by a theme update or a Tailwind rebuild, and the test then silently stops applying while GTM keeps reporting impressions.
3. Register the parameter in GA4 — the step that breaks most GTM tests
Pushing ab_variant into the data layer is not enough. GA4 collects unregistered event parameters but does not expose them anywhere except Realtime and DebugView. Until you open Admin → Custom definitions → Custom dimensions, create an event-scoped dimension, and type the parameter name exactly as it arrives (ab_variant), your standard reports will show the conversions but no way to split them by variant. Registration is not retroactive either — the dimension only starts populating from the moment you create it, and takes up to 24 hours to appear.
Standard GA4 properties allow 50 event-scoped custom dimensions, so budget them rather than creating one per test.
4. Read the result
Build an exploration with ab_variant as the row dimension and your conversion event as the metric. GA4 will not tell you whether the difference is real — it has no significance testing — so you will need to run the numbers yourself. Our guide to minimum detectable effect covers how big a difference you can actually expect to detect at your traffic level, which is worth checking before you launch rather than after.
What You Can Test with GTM
GTM-based A/B tests work best for simple, client-side changes:
- Headlines and CTA copy (see our guide on A/B testing headline copy)
- Button colors and placement
- Hiding or showing page elements
- Swapping images or banners
If you're just learning how to run an A/B test, GTM can be a decent starting point because the tooling is already on your site.
The Real Problems with GTM A/B Testing
Here's what most "GTM testing tutorials" skip: GTM loads asynchronously. Even on an Initialization trigger, the container itself has to download and execute before any of your tags run, so your variant code fires after the page has already started rendering. Visitors see the original version flash before the variant kicks in — the dreaded flicker effect.
This isn't a minor annoyance. Flicker actively harms your test data. Visitors who see the original content — even for 200 milliseconds — form a first impression that skews their behavior. Your variant might actually be better, but flicker pollutes the signal.
Other practical limitations:
- No visual editor. Every change requires writing JavaScript to target and modify DOM elements. For teams without developers, this is a blocker.
- No built-in statistics. GTM doesn't calculate statistical significance. You have to export GA4 data and run your own analysis or rely on GA4's limited reporting.
- No experiment management. There's no dashboard to start, stop, or monitor tests. You manage everything through GTM tags, triggers, and variables — which gets messy fast with multiple concurrent tests.
- Cookie consent complications. Your split-test cookie requires consent under GDPR, adding another compliance layer to manage.
When GTM Testing Makes Sense
GTM-based A/B testing is a reasonable choice when:
- You're running a one-off test and already have GTM and GA4 set up
- You have a developer comfortable writing JavaScript DOM manipulation
- You don't need real-time results or statistical significance calculations
- You're on a team that already lives in the Google analytics ecosystem
For anything beyond a quick single-element test, the maintenance burden adds up quickly.
A Simpler Alternative: Skip the JavaScript
If you want to run tests without writing JavaScript, managing cookies, or fighting flicker, PageDuel gives you a visual editor that handles all of it. Drop a single script tag on your site — you can even deploy it through GTM itself — and use the point-and-click editor to create variants. PageDuel handles randomization, cookie management, anti-flicker protection, and statistical significance automatically.
It starts with a 14-day free trial and no credit card, then usage-based plans from $9/month, which makes it a practical Google Optimize replacement for teams who don't want to cobble together a GTM-based testing stack. Unlike the GTM route, significance is calculated for you and the anti-flicker step is built in rather than something you engineer around.
Setting Up PageDuel via GTM (2 Minutes)
If you prefer to manage all your scripts through GTM, you can deploy PageDuel as a Custom HTML tag:
- Create a new Custom HTML tag in GTM
- Paste your PageDuel snippet (found in your dashboard under Site Settings)
- Set the trigger to "All Pages"
- Publish your GTM container
From there, everything — variant creation, traffic splitting, results tracking — happens in the PageDuel dashboard. No more JavaScript debugging in GTM preview mode.
Bottom Line
GTM can technically run A/B tests, and for a quick one-off experiment with developer support, it works. But for any team that wants to test regularly — especially without writing code — a dedicated tool saves hours of setup and avoids the flicker and analytics gaps that make GTM tests unreliable. Start with what you have, but know when to upgrade.
Related Reading
- How to Track A/B Tests in GA4: The Complete Setup Guide for 2026
- How to Run an A/B Test: A Complete Step-by-Step Guide
- A/B Testing Without Coding: How Non-Technical Teams Run Experiments
- The Best Google Optimize Alternative in 2026
- The Best Free A/B Testing Tool in 2026
- A/B Testing Google Ads Campaigns: The 2026 Playbook for Smarter Ad Spend
- Minimum Detectable Effect in A/B Testing: How Small a Lift Can You Actually Measure?
Ready to test this on your own site?
PageDuel pairs free, privacy-friendly analytics with no-code A/B testing and revenue attribution — so you can find a leak, fix it, and prove the fix made money.
14-day free trial · No credit card required