Created
March 29, 2023 10:08
-
-
Save sladg/0c0893cece0c9c3bd63d9f53eb9ae9b1 to your computer and use it in GitHub Desktop.
Free way how to connect your GTM onto Shopify without additional plugins or apps.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// use "{{ 'analytics-head.js' | asset_url | script_tag }}" inside your liquid files. Namely `theme.liquid`. | |
var layerName = 'customDataLayer' | |
var gtmId = 'GTM-XXXXXX' | |
// ------------------------------ | |
// Load GTM in head, initialize dataLayer. | |
;(function (w, d, s, l, i) { | |
console.log('Initializing GTM ...') | |
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) | |
console.log('GTM initiliazed.') | |
})(window, document, 'script', layerName, gtmId) | |
// ------------------------------ | |
// Put GTM script into body. | |
// ------------------------------ | |
var noscriptWrapper = document.createElement('noscript') | |
var gtmIframe = document.createElement('iframe') | |
gtmIframe.src = 'https://www.googletagmanager.com/ns.html?id=' + gtmId | |
gtmIframe.height = '0' | |
gtmIframe.width = '0' | |
gtmIframe.style = 'display:none;visibility:hidden' | |
noscriptWrapper.appendChild(gtmIframe) | |
var appendBodyInterval = setInterval(function () { | |
if (document.body) { | |
document.body.appendChild(noscriptWrapper) | |
clearInterval(appendBodyInterval) | |
} | |
}, 50) | |
console.log('GTM script added to body.') | |
// ------------------------------ | |
// ------------------------------ | |
// Duplicate Shopify's dataLayer to our customDataLayer. | |
// We are storing previous state of dataLayer in localStorage, this ensures we can reliable detect new events. | |
// Comparing customDataLayer with dataLayer is not reliable, because we can have additional, custom events coming from GTM's config. | |
setInterval(function () { | |
const currentPage = window.location.pathname | |
const previousState = window.localStorage.getItem('shopifyAnalyticsPreviousState') | |
if (previousState && JSON.parse(previousState).path !== currentPage && JSON.parse(previousState).len > 0) { | |
console.log('Page changed. Resetting state ...') | |
window.localStorage.setItem('shopifyAnalyticsPreviousState', JSON.stringify({ path: currentPage, len: 0 })) | |
} | |
if ((window.dataLayer || []).length > ((previousState && JSON.parse(previousState).len) || 0)) { | |
console.log('New dataLayer event detected. Pushing to customDataLayer ...') | |
// @TODO: Check previous and current length. Cycle through dataLayer and push only new events (even if multiple events are pushed at once). | |
window.customDataLayer.push(window.dataLayer[window.dataLayer.length - 1]) | |
window.localStorage.setItem('shopifyAnalyticsPreviousState', JSON.stringify({ path: currentPage, len: window.dataLayer.length })) | |
} | |
}, 50) | |
// ------------------------------ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment