How to Set Up Google Tag Manager on Shopify (Without Breaking Your Site Speed)
Written by Ildi Veliu
Most Shopify stores we audit have the same tracking setup: scripts pasted directly into theme.liquid, no version control, and no clear picture of what is actually firing on every page load.
Done wrong, GTM adds more JavaScript weight to every page load than the scripts it was meant to replace. Here is the setup that avoids that.
What is Google Tag Manager and why do you need it?
Google Tag Manager is a tag management system that lets you deploy and manage tracking scripts from one place without touching your theme code every time. GA4, Meta Pixel, conversion tags, heatmaps: all managed through one interface.
Without it, every new pixel is added directly to theme.liquid. Your developer gets pulled in for every marketing request. Scripts accumulate with no record of what was added or when. When something breaks, you are searching through raw theme code trying to find which snippet is causing the problem.
GTM puts all of that under control. Version history, a testing environment, and the ability to manage tags without a code deployment.
Step 1: Create your GTM account and container
The initial setup is straightforward, as most Google tools are. First, go totagmanager.google.com and create an account.
Account setup:
Account name: your brand or company name
Country: your location
Data sharing checkbox: optional, leave it unchecked if you prefer
Container setup:
Container name: your domain, for example, yourstore.com
Target platform: Web
Click Create, and your container is ready.
On the main Dashboard, your container ID appears at the top of the workspace. It looks like GTM-XXXXXXX.
Before you move on: if you manage multiple stores or have a staging environment, create a separate container for each. Mixing environments in one container means test tags fire on live traffic. We have seen this cause reporting problems that take days to trace back to the source.
Step 2: Add GTM to your Shopify theme
You will then need to add the Google Tag Manager scripts to your website.
Go to Online Store > Themes in your Shopify admin. Next to your active theme, click the three-dot menu and select Edit code. Open layout > theme.liquid.
You need two scripts.
Script 1. As high as possible inside the <head> tag:
html<!-- Google Tag Manager --><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><!-- End Google Tag Manager -->
Script 2. Immediately after the opening <body> tag:
html<!-- Google Tag Manager (noscript) --><noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-XXXXXXX"height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript><!-- End Google Tag Manager (noscript) -->
Replace GTM-XXXXXXX with your container ID in both snippets. Save.
Check this before moving on. If your theme.liquid already has a hardcoded <!-- Google tag (gtag.js) --> block, installed directly or added by an app, you have a conflict. Running a hardcoded GA4 snippet alongside a GA4 tag inside GTM sends duplicate pageview events to your property. Every session gets counted twice.
We recommend removing the hardcoded snippet entirely and letting GTM manage GA4 exclusively. This is one of the first things we check in any tracking audit, and it comes up more often than it should.
Step 3: Configure your first tag and trigger
Click Tags in the left sidebar, then New.
Tag name: GA4 - Pageview
Tag type: Google Tag (under the Google section)
Tag ID: your GA4 Measurement ID, format G-XXXXXXXXXX
Find your Measurement ID in GA4 under Admin > Data Streams > your stream > Measurement ID.
Add one configuration parameter: send_page_view set to true.
Trigger setup:
Under Triggering, create a new trigger:
Trigger name: All Pages
Trigger type: Page View
Fire on: All Page Views
Save the trigger. Save the tag.
“All Pages” is correct for a pageview tag. It is not correct for most other tags. A conversion pixel or heatmap tool firing on every page view runs unnecessary JavaScript on pages where it does nothing.
Step 4: Test in GTM Preview mode before publishing
Click Preview in the top-right of your workspace. Enter your store URL and click Connect. Your store opens in a new tab with Tag Assistant active. You will see "Tag Assistant Connected" at the bottom of the page. The debugger panel shows Tags Fired and Tags Not Fired for each page event.
Your GA4 Pageview tag should appear under Tags Fired on the initial page load. Click through to a product page and confirm it fires there too.
If a tag shows under Tags Not Fired, click it. GTM shows you exactly which trigger condition was not met. That is almost always faster than debugging it on the tag configuration screen.
One important limitation to know:GTM installed via theme.liquid does not fire on Shopify's checkout or thank-you pages. Checkout tracking requires a separate setup using Shopify's Custom Pixel system, configured under Settings > Customer Events.
If purchase conversion tags are part of your tracking requirements, that is a separate implementation from what this guide covers. Thoroughly test what you have set up in Preview mode on storefront pages, and plan the checkout pixel setup as a follow-on step.
Step 5: Publish your container
Click Submit in the top-right. Name your version before publishing:
Good: GA4 pageview tag - initial setup
Not useful: Version 2
Click Publish. Your container is live.
Name every publish. When something breaks in three months and you are scanning 15 container versions, the one with a clear name is the one you find immediately.
We recommend treating version names the same way you would treat commit messages in a codebase: specific enough that someone else on the team can understand what changed without opening it.
How GTM affects Shopify site speed, and the fix that actually works
This is the part most setup guides skip.
On a standard installation, GTM fetches the container script and all tag scripts immediately on page load.
On this Shopify store, the GTM tag added 430.9 KiB of network payload for a Lighthouse Performance score of 91.
What is deferred loading?
The standard snippet fires GTM as soon as the browser hits the <head>. Deferred loading is an instruction that delays GTM until the user takes action: scrolls, clicks, moves the mouse, or presses a key.
For most Shopify stores, this is the right tradeoff. Your meaningful tracking events, add to cart, checkout steps, purchase, are all triggered by interaction anyway. A pageview that fires 300 milliseconds after the first scroll does not hurt your analytics. It does help your Lighthouse score and your real-user Core Web Vitals.
How to implement it
In your theme.liquid, replace the standard GTM <head> snippet with this:
html<!-- Google Tag Manager (deferred load, immediate dataLayer init) --><script> window.dataLayer = window.dataLayer || []; window.dataLayer.push({ 'gtm.start': new Date().getTime(), event: 'gtm.js' }); (function () { var GTM_ID = 'GTM-XXXXXXX'; var loaded = false; function loadGTM() { if (loaded) return; loaded = true; var s = document.createElement('script'); s.async = true; s.src = 'https://www.googletagmanager.com/gtm.js?id=' + GTM_ID; document.head.appendChild(s); } var events = ['scroll', 'mousemove', 'touchstart', 'keydown', 'click']; events.forEach(function (e) { window.addEventListener(e, loadGTM, { once: true, passive: true }); }); if ('requestIdleCallback' in window) { requestIdleCallback(loadGTM, { timeout: 3000 }); } else { setTimeout(loadGTM, 3000); } })();</script><!-- End Google Tag Manager -->
Replace GTM-XXXXXXX with your container ID. The noscript <body> snippet stays unchanged.
What this code does, plainly:
The dataLayer initializes immediately, so no pre-GTM events are lost. GTM itself loads only on the first user interaction. The requestIdleCallback fallback with a 3,000ms timeout means if the user does nothing for three seconds, GTM loads anyway. Bots, crawlers, and quick bounces still get captured.
The passive: true flag on the event listeners is worth paying attention to. It tells the browser these listeners will not block scroll or touch handling. Without it, adding scroll listeners can itself hurt INP, which defeats the purpose of the whole approach.
What this means for INP
Across our speed benchmark of 1,000 Shopify stores, the median INP was 153 milliseconds, within Google's recommended 200ms threshold. Stores running standard GTM with five or more All Pages tags consistently came in higher.
Deferred loading alone will not fix a slow store. It removes a variable that has no business on the main thread before the user scrolls, freeing the browser to handle the initial render without competing tag scripts.
After switching to deferred loading for the same store in the example above, GTM's payload was entirely absent from the initial load. Performance score: 93 (+2 Improvement) Same store, same content, one change.
If your container has grown past ten active tags and INP is consistentlyabove 200 milliseconds, deferred client-side loading has a ceiling.
Most GTM problems on Shopify come from the same setup errors, repeated across stores.
Duplicate tags. A hardcoded GA4 snippet in your theme, plus a GA4 tag inside GTM, means double-counted sessions. Remove the hardcoded version and let GTM manage it exclusively.
Assuming checkout tracking works out of the box. GTM via theme.liquid does not fire on checkout or thank-you pages. Conversion tracking for the full purchase funnel requires Shopify's Custom Pixel system. Plan for it separately.
All Pages on everything. Every tag firing on every page view adds JavaScript overhead to pages that have no use for it. Match triggers precisely.
Unpublished drafts. GTM does not auto-publish. Agree as a team: changes get tested and published or discarded the same day. Drafts sitting for weeks create confusion about what is actually live on the store.
No version names. Ten seconds per publish. Saves hours later.
The container you set up today is the one you will manage for years
GTM is invisible when it works. Tags managed cleanly, marketing independent from developers, and performance where it should be.
The problems start when the container grows without oversight. Tags accumulate. Triggers get duplicated. Nobody tracks what the container is costing you across the site.
The deferred loading approach removes GTM from the parts of your page load that matter most. Combined with trigger discipline as the container grows, it keeps your analytics stack running without becoming a performance drag.
If you want a review of your current GTM container or analytics setup, talk to our team.
F.A.Qs about Google Tag Manager on Shopify
Most Shopify stores we audit have the same tracking setup: scripts pasted directly into theme.liquid, no version control, and no clear picture of what is actually firing on every page load.
Done wrong, GTM adds more JavaScript weight to every page load than the scripts it was meant to replace. Here is the setup that avoids that.
What is Google Tag Manager and why do you need it?
Google Tag Manager is a tag management system that lets you deploy and manage tracking scripts from one place without touching your theme code every time. GA4, Meta Pixel, conversion tags, heatmaps: all managed through one interface.
Without it, every new pixel is added directly to theme.liquid. Your developer gets pulled in for every marketing request. Scripts accumulate with no record of what was added or when. When something breaks, you are searching through raw theme code trying to find which snippet is causing the problem.
GTM puts all of that under control. Version history, a testing environment, and the ability to manage tags without a code deployment.
Step 1: Create your GTM account and container
The initial setup is straightforward, as most Google tools are. First, go totagmanager.google.com and create an account.
Account setup:
Account name: your brand or company name
Country: your location
Data sharing checkbox: optional, leave it unchecked if you prefer
Container setup:
Container name: your domain, for example, yourstore.com
Target platform: Web
Click Create, and your container is ready.
On the main Dashboard, your container ID appears at the top of the workspace. It looks like GTM-XXXXXXX.
Before you move on: if you manage multiple stores or have a staging environment, create a separate container for each. Mixing environments in one container means test tags fire on live traffic. We have seen this cause reporting problems that take days to trace back to the source.
Step 2: Add GTM to your Shopify theme
You will then need to add the Google Tag Manager scripts to your website.
Go to Online Store > Themes in your Shopify admin. Next to your active theme, click the three-dot menu and select Edit code. Open layout > theme.liquid.
You need two scripts.
Script 1. As high as possible inside the <head> tag:
html<!-- Google Tag Manager --><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><!-- End Google Tag Manager -->
Script 2. Immediately after the opening <body> tag:
html<!-- Google Tag Manager (noscript) --><noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-XXXXXXX"height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript><!-- End Google Tag Manager (noscript) -->
Replace GTM-XXXXXXX with your container ID in both snippets. Save.
Check this before moving on. If your theme.liquid already has a hardcoded <!-- Google tag (gtag.js) --> block, installed directly or added by an app, you have a conflict. Running a hardcoded GA4 snippet alongside a GA4 tag inside GTM sends duplicate pageview events to your property. Every session gets counted twice.
We recommend removing the hardcoded snippet entirely and letting GTM manage GA4 exclusively. This is one of the first things we check in any tracking audit, and it comes up more often than it should.
Step 3: Configure your first tag and trigger
Click Tags in the left sidebar, then New.
Tag name: GA4 - Pageview
Tag type: Google Tag (under the Google section)
Tag ID: your GA4 Measurement ID, format G-XXXXXXXXXX
Find your Measurement ID in GA4 under Admin > Data Streams > your stream > Measurement ID.
Add one configuration parameter: send_page_view set to true.
Trigger setup:
Under Triggering, create a new trigger:
Trigger name: All Pages
Trigger type: Page View
Fire on: All Page Views
Save the trigger. Save the tag.
“All Pages” is correct for a pageview tag. It is not correct for most other tags. A conversion pixel or heatmap tool firing on every page view runs unnecessary JavaScript on pages where it does nothing.
Step 4: Test in GTM Preview mode before publishing
Click Preview in the top-right of your workspace. Enter your store URL and click Connect. Your store opens in a new tab with Tag Assistant active. You will see "Tag Assistant Connected" at the bottom of the page. The debugger panel shows Tags Fired and Tags Not Fired for each page event.
Your GA4 Pageview tag should appear under Tags Fired on the initial page load. Click through to a product page and confirm it fires there too.
If a tag shows under Tags Not Fired, click it. GTM shows you exactly which trigger condition was not met. That is almost always faster than debugging it on the tag configuration screen.
One important limitation to know:GTM installed via theme.liquid does not fire on Shopify's checkout or thank-you pages. Checkout tracking requires a separate setup using Shopify's Custom Pixel system, configured under Settings > Customer Events.
If purchase conversion tags are part of your tracking requirements, that is a separate implementation from what this guide covers. Thoroughly test what you have set up in Preview mode on storefront pages, and plan the checkout pixel setup as a follow-on step.
Step 5: Publish your container
Click Submit in the top-right. Name your version before publishing:
Good: GA4 pageview tag - initial setup
Not useful: Version 2
Click Publish. Your container is live.
Name every publish. When something breaks in three months and you are scanning 15 container versions, the one with a clear name is the one you find immediately.
We recommend treating version names the same way you would treat commit messages in a codebase: specific enough that someone else on the team can understand what changed without opening it.
How GTM affects Shopify site speed, and the fix that actually works
This is the part most setup guides skip.
On a standard installation, GTM fetches the container script and all tag scripts immediately on page load.
On this Shopify store, the GTM tag added 430.9 KiB of network payload for a Lighthouse Performance score of 91.
What is deferred loading?
The standard snippet fires GTM as soon as the browser hits the <head>. Deferred loading is an instruction that delays GTM until the user takes action: scrolls, clicks, moves the mouse, or presses a key.
For most Shopify stores, this is the right tradeoff. Your meaningful tracking events, add to cart, checkout steps, purchase, are all triggered by interaction anyway. A pageview that fires 300 milliseconds after the first scroll does not hurt your analytics. It does help your Lighthouse score and your real-user Core Web Vitals.
How to implement it
In your theme.liquid, replace the standard GTM <head> snippet with this:
html<!-- Google Tag Manager (deferred load, immediate dataLayer init) --><script> window.dataLayer = window.dataLayer || []; window.dataLayer.push({ 'gtm.start': new Date().getTime(), event: 'gtm.js' }); (function () { var GTM_ID = 'GTM-XXXXXXX'; var loaded = false; function loadGTM() { if (loaded) return; loaded = true; var s = document.createElement('script'); s.async = true; s.src = 'https://www.googletagmanager.com/gtm.js?id=' + GTM_ID; document.head.appendChild(s); } var events = ['scroll', 'mousemove', 'touchstart', 'keydown', 'click']; events.forEach(function (e) { window.addEventListener(e, loadGTM, { once: true, passive: true }); }); if ('requestIdleCallback' in window) { requestIdleCallback(loadGTM, { timeout: 3000 }); } else { setTimeout(loadGTM, 3000); } })();</script><!-- End Google Tag Manager -->
Replace GTM-XXXXXXX with your container ID. The noscript <body> snippet stays unchanged.
What this code does, plainly:
The dataLayer initializes immediately, so no pre-GTM events are lost. GTM itself loads only on the first user interaction. The requestIdleCallback fallback with a 3,000ms timeout means if the user does nothing for three seconds, GTM loads anyway. Bots, crawlers, and quick bounces still get captured.
The passive: true flag on the event listeners is worth paying attention to. It tells the browser these listeners will not block scroll or touch handling. Without it, adding scroll listeners can itself hurt INP, which defeats the purpose of the whole approach.
What this means for INP
Across our speed benchmark of 1,000 Shopify stores, the median INP was 153 milliseconds, within Google's recommended 200ms threshold. Stores running standard GTM with five or more All Pages tags consistently came in higher.
Deferred loading alone will not fix a slow store. It removes a variable that has no business on the main thread before the user scrolls, freeing the browser to handle the initial render without competing tag scripts.
After switching to deferred loading for the same store in the example above, GTM's payload was entirely absent from the initial load. Performance score: 93 (+2 Improvement) Same store, same content, one change.
If your container has grown past ten active tags and INP is consistentlyabove 200 milliseconds, deferred client-side loading has a ceiling.
Most GTM problems on Shopify come from the same setup errors, repeated across stores.
Duplicate tags. A hardcoded GA4 snippet in your theme, plus a GA4 tag inside GTM, means double-counted sessions. Remove the hardcoded version and let GTM manage it exclusively.
Assuming checkout tracking works out of the box. GTM via theme.liquid does not fire on checkout or thank-you pages. Conversion tracking for the full purchase funnel requires Shopify's Custom Pixel system. Plan for it separately.
All Pages on everything. Every tag firing on every page view adds JavaScript overhead to pages that have no use for it. Match triggers precisely.
Unpublished drafts. GTM does not auto-publish. Agree as a team: changes get tested and published or discarded the same day. Drafts sitting for weeks create confusion about what is actually live on the store.
No version names. Ten seconds per publish. Saves hours later.
The container you set up today is the one you will manage for years
GTM is invisible when it works. Tags managed cleanly, marketing independent from developers, and performance where it should be.
The problems start when the container grows without oversight. Tags accumulate. Triggers get duplicated. Nobody tracks what the container is costing you across the site.
The deferred loading approach removes GTM from the parts of your page load that matter most. Combined with trigger discipline as the container grows, it keeps your analytics stack running without becoming a performance drag.
If you want a review of your current GTM container or analytics setup, talk to our team.
F.A.Qs about Google Tag Manager on Shopify
01 Do I need to update my GTM setup when I change Shopify themes?
Yes. When you switch to a new theme, the GTM snippets in your old theme.liquid do not carry over automatically. You need to add both scripts to the new theme before publishing it. Check this in Preview mode before the new theme goes live.
02Will GTM break if I install a Shopify pixel app?
The GTM setup in Shopify can break if you install a Shopify pixel app. Some pixel apps install their own version of GA4 or Meta Pixel directly into the theme, which creates duplicate tags when GTM is also firing the same scripts. Always check theme.liquid after installing any marketing or tracking app.
03Does GTM replace the need for Shopify's native Google and YouTube app?
Not entirely. GTM handles your custom tags and tracking scripts. The Google and YouTube app handles the connection between Shopify's order data and Google's ad measurement, particularly for checkout and post-purchase events. For most stores, both are running alongside each other. The important thing is making sure they are not firing the same GA4 or Google Ads tags twice.
04How do I know if my GTM setup is actually working correctly?
Preview mode tells you whether tags are firing. It does not tell you whether the data reaching GA4 or your ad platforms is accurate. Duplicate events, missing parameters, and broken ecommerce tracking are all invisible in Preview mode.
If your store has grown past the basic setup, or you are making budget decisions based on conversion data, a full tracking audit is worth doing. We audit GTM containers and GA4 properties for Shopify stores as part of our analytics service. reviewing what is firing, what is duplicated, what is missing, and whether the data you are acting on is accurate. If you want a second set of eyes on your setup, talk to our team.
05 Can two Shopify apps install conflicting GTM containers?
Yes. Some marketing and tracking apps install their own GTM container directly into your theme without telling you. If you already have a container installed, you end up with two GTM snippets loading on every page. The fix is to open your theme.liquid and search for "googletagmanager.com"; if it appears more than twice, you have a conflict. Identify which container belongs to the app and decide whether to consolidate or remove it.
Ildi Veliu
Ildi is a Technical SEO Specialist at Shero Commerce on a mission to help websites unlock their full organic potential. With a background in Informatics-Economics, he bridges the gap between technical web development and search engine algorithms, specializing in technical audits and search performance strategy. He is always looking for new ways to outsmart the algorithms and drive high-intent organic traffic.