AuditTags
GTMShopifyTroubleshootingDuplicate EventsTag Management

GTM Container Firing Twice on Shopify — How to Find It and Stop It

A GTM container loading twice doubles every event count and wrecks attribution. Here is how to detect it and which Shopify setups cause it.

A
AuditTags Engineering
Shopify Analytics Specialists
10 min read
GTM Container Firing Twice on Shopify — How to Find It and Stop It

Here's something that will ruin your Monday morning: you open GA4, and your purchase event count is exactly double what your Shopify order count shows. Not roughly double. Exactly double. Every single conversion, firing twice.

Your ad platform thinks you're crushing it. Your actual revenue says otherwise. And somewhere in the gap between those two numbers, your entire attribution model is quietly falling apart.

This is the GTM container firing twice problem. It's more common than you'd think, it's surprisingly easy to create by accident, and most merchants have no idea it's happening until they notice something feels off about their data.

Let's fix that.


Why a Duplicate GTM Container Is So Damaging

Think of your GTM container like a megaphone at a concert. One megaphone, one PA system — the crowd hears the music once. Now imagine someone accidentally plugs in two identical PA systems feeding the same signal. The crowd hears everything twice, slightly out of sync, and nobody can figure out why the acoustics sound weird.

That's exactly what happens when GTM loads twice on your Shopify store. Every tag fires twice. Every trigger evaluates twice. Every dataLayer.push() gets picked up twice. The result is doubled event counts across GA4, Facebook Pixel, TikTok — any platform that receives data through that container.

The consequences stack up fast:

  • Purchase events double, which means your ROAS calculations are wrong
  • Add-to-cart and checkout events inflate, feeding garbage signals to your ad algorithms
  • Session counts can skew, especially if pageview tags fire twice on load
  • Conversion deduplication becomes a mess because you're now working against yourself

And here's the sneaky part — the data looks plausible. It's not random noise. Everything is exactly doubled, which can actually make it harder to catch. Humans are bad at noticing proportional problems when there's no obvious reference point.


The Four Most Common Ways This Happens on Shopify

Shopify's architecture creates specific opportunities for GTM to load twice. None of these are bugs in GTM itself — they're all setup mistakes, and they all have patterns you can look for.

1. GTM in the Theme and in Shopify's Native "Google Tag Manager" App

This is the most common culprit. Shopify has a built-in Google & YouTube app (and previously a dedicated GTM integration) that injects container code automatically. If you — or an agency before you — also added GTM manually to your theme.liquid file, you're loading the container from two different sources.

The theme code looks like this:

<!-- In theme.liquid, inside <head> -->
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','GTM-XXXXXXX');</script>

<!-- Also in theme.liquid, after <body> -->
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-XXXXXXX"
height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>

And the Shopify app injects its own version in parallel. Same container ID, different injection point, double the events.

2. GTM Injected by a Third-Party App and Manually in the Theme

Cookie consent platforms, analytics apps, and heatmap tools sometimes inject their own GTM snippet as part of their setup process. If you already had GTM in your theme, you now have two copies running.

This is especially tricky because the second injection is often invisible — it happens inside an app's backend, not in any file you can easily inspect.

3. Duplicate Snippet in theme.liquid Itself

Shopify themes get edited. Agencies hand off to in-house teams. In-house teams hand off to other agencies. Someone added GTM, then someone else "added GTM" not knowing it was already there.

Check your theme.liquid for two separate GTM snippet blocks. It happens more than you'd expect, and a broken theme update is often the moment it sneaks in — a fresh theme copy gets the snippet added again without anyone auditing what was already there.

4. GTM Loading on the Checkout Pages via Additional Scripts and the Theme

Shopify's checkout customization works differently from the rest of the store. The theme.liquid file doesn't apply to /checkout/* pages — instead, scripts load via the "Additional Scripts" section in checkout settings (or via checkout extensibility for newer stores).

It's completely possible — and common — to have:

  • GTM in theme.liquid (covers all non-checkout pages)
  • GTM in "Additional Scripts" (covers checkout pages)
  • GTM in both places on whatever pages the checkout flow initiates from, like the cart page

This is actually a different flavor of the problem. The duplication isn't site-wide — it's isolated to specific funnel stages. Which makes the purchase and begin-checkout events fire twice while everything else looks fine.


How to Detect a Duplicate GTM Container

Don't guess. Verify.

Method 1: Google Tag Assistant

Open Chrome with Tag Assistant and browse your store. Navigate from homepage → product page → cart → checkout. Look at the container count in the Tag Assistant panel.

If you see your GTM container ID appearing twice in the same page summary, you have duplication. Tag Assistant will also show you the firing sequence, which helps identify which page type is affected.

Method 2: Browser DevTools Network Tab

Open DevTools, go to the Network tab, and filter by gtm.js. Reload the page. If you see two requests to googletagmanager.com/gtm.js?id=GTM-XXXXXXX, that's your confirmation. Two network requests, two container instances, two of everything.

// You can also check this in the console
// A healthy store has dataLayer as a single array
// A store with duplicate GTM often shows the initialization event twice

window.dataLayer.filter(event => event.event === 'gtm.js')
// Healthy: returns 1 item
// Broken: returns 2 items

Method 3: Check the dataLayer Directly

Open the browser console on the page you suspect and run:

window.dataLayer.filter(e => e.event === 'gtm.js').length

One result: you're fine. Two results: you have a duplicate container instance. This is the fastest way to verify programmatically without any additional tools.

Method 4: GA4 DebugView

Enable GA4 DebugView and walk through a purchase flow. Watch the event stream in real time. If you see purchase appearing twice within a second or two of each other, with identical transaction_id values, that's duplicate firing. This pairs well with the content in our post on duplicate purchase events in GA4 — the resolution steps are different depending on whether the root cause is GTM duplication or something else.


How to Fix It

The fix depends on where the duplication is coming from. There's no universal patch — you need to trace the source first.

Fix 1: Audit Every Place GTM Can Be Injected

Go through this checklist systematically:

  1. theme.liquid — Search for GTM- or googletagmanager.com. Count instances.
  2. Shopify Admin → Online Store → Preferences — Google Analytics field. Does it have a GTM container ID there?
  3. Shopify Apps — Check every installed app for GTM or "Google Tag Manager" in its settings
  4. Checkout Settings → Additional Scripts — Search for GTM-
  5. Checkout extensibility blocks — If you're on a newer Shopify plan with checkout customization, audit your checkout blocks

Fix 2: Remove the Duplicate, Don't "Disable" It

This sounds obvious but people often leave code commented out instead of deleting it. A commented snippet won't fire, but it creates confusion for the next person who audits the theme and assumes there's only one "location" to manage.

Delete the duplicate. Commit the change with a clear message. Document where GTM is supposed to live.

Fix 3: Standardize on One Injection Method

Pick a lane: either manage GTM manually in theme.liquid, or let a Shopify integration handle it — but never both. The manual approach gives you more control. The app approach is easier to manage without developer access. Either works. Both at once doesn't.

For checkout events specifically, use Shopify's Web Pixel API or Customer Events (available in the Shopify Admin) rather than injecting GTM snippets into additional scripts. This is the current best-practice approach that avoids the checkout duplication problem entirely.

Fix 4: Add a Container Load Guard (Optional, But Smart)

If you're working in an environment where multiple teams have access to the theme, a guard clause can prevent future duplication:

// Load GTM only if it hasn't already been initialized
if (!window.google_tag_manager || !window.google_tag_manager['GTM-XXXXXXX']) {
  (function(w,d,s,l,i){
    w[l]=w[l]||[];
    w[l].push({'gtm.start': new Date().getTime(), event:'gtm.js'});
    var f=d.getElementsByTagName(s)[0],
        j=d.createElement(s),
        dl=l!='dataLayer'?'&l='+l:'';
    j.async=true;
    j.src='https://www.googletagmanager.com/gtm.js?id='+i+dl;
    f.parentNode.insertBefore(j,f);
  })(window,document,'script','dataLayer','GTM-XXXXXXX');
}

This isn't a substitute for fixing the root cause, but it's a reasonable safety net in complex environments. Think of it as a circuit breaker, not a solution.


What Happens to Your Data After You Fix It

Don't expect your GA4 numbers to suddenly look half as good — they will, and that's correct. Your real conversion rate didn't change. Your actual revenue didn't drop. You're just finally looking at accurate numbers instead of inflated ones.

A few things to do after fixing a duplicate GTM setup:

Annotate GA4. Add a data annotation marking the date you fixed the duplication. Anyone looking at historical data will need that context to understand the drop.

Recalibrate your benchmarks. If your "average" ROAS was calculated against doubled conversion data, your benchmarks are wrong. Give yourself at least 30 days of clean data before making big budget decisions.

Audit your ad platform conversions. If you were importing GA4 conversions into Google Ads or Meta, your bid strategies may have been optimizing against inflated data. This takes time for the algorithms to recalibrate.

Watch for the phantom problem. Sometimes fixing GTM duplication exposes a different issue — events that were always broken but were masked by the noise of doubled data. Our post on GA4 tag misfires and their causes covers what to look for in that cleanup phase.


Don't Confuse Duplicate Containers with Duplicate Tags

These are related but different problems. A duplicate GTM container means the entire container loads twice — every tag, every trigger, every variable. It's a systemic problem.

A duplicate tag means a specific tag fires twice, even with a single container load. That can happen because of overlapping triggers, incorrect event deduplication logic, or a tag configured to fire on both "All Pages" and a redundant custom trigger.

Both produce inflated data, but the fix is completely different. If you've confirmed via DevTools that you only have one gtm.js request but you're still seeing doubled purchase events in GA4, you're dealing with tag-level duplication rather than container-level duplication.


Automated Validation with AuditTags

Manually hunting through theme.liquid, checking checkout scripts, and digging through DevTools works — but it's slow, it requires someone technical to do it, and it only catches what you think to look for at the moment you look.

AuditTags scans your Shopify store for GTM container duplication as part of its standard audit. When we detect multiple instances of the same container ID loading on the same page, we flag it at the page level — so you can see whether the problem exists on product pages, the cart, the order status page, or all of the above.

Beyond container-level detection, AuditTags validates that your dataLayer is receiving each event exactly once per user action. If a purchase event fires twice within the same pageview, that's surfaced in your audit report — separately from the container loading issue, because the root cause matters for how you fix it.

The audit also checks your checkout configuration specifically, since that's where the Additional Scripts duplication pattern tends to hide. Most generic GTM audits don't inspect checkout separately. We do, because that's where the most expensive events in your funnel actually happen.

If you've ever had an agency set up GTM, then had another agency "fix" it, then made some theme changes yourself, there's a real chance your container is loading more than once somewhere in your funnel. AuditTags will tell you exactly where.


See If This Pattern Exists in Your Store

Run a free preview scan to detect tracking patterns, duplicate tags, and configuration drift on your Shopify site.

Run Free Preview Scan

Or View sample report to see what you'll get.