Skip to content

Instantly share code, notes, and snippets.

@sladg
Created March 29, 2023 10:08
Show Gist options
  • Save sladg/0c0893cece0c9c3bd63d9f53eb9ae9b1 to your computer and use it in GitHub Desktop.
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.
// 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