1. No allocated client development resources or IT buy-in, or IT dept on-boarding training process.


  1. No tactical planning:
    • Is the client rolling-out on one domain first or all-in-one-go?
    • If one domain first is this blog or site-section first or all-in-one-go?
    • Is the client running in fast migration sprints or single monthly releases (e.g. global header, then ecommerce page, then events & customVars)?
  2. No technical planning:
    • Has position of GTM been confirmed – i.e. is adding code to top <body> tag a problem?
    • Are plugins or custom code going to be used to enabled GTM and dataLayer?
    • What scanners (if any) are going to be used pre and post migration?
    • Determine method for dynamically setting GA-xxxxx-x via lookup table for hostname or GTM-xxxx.
  3. No naming conventions plan:
    • DataLayer names are not consistent with fixed GTM ecommerce names or W3C names.
    • Not defaulting to camelCase capitalisation on dataLayer names (very common)
    • Not defaulting to lowercase dataLayer values (very common)
  4. No QA planning process:
    • No separate GA accountID for Dev traffic and testing (UA-00000-2)
    • GTM code not previewed and debugged before publishing.
    • Chrome Tag Assist not used to debug
      • Unescaped commas & single quotations in dataLayer by developers.
      • GTM placed in nested <div> OR in <head> causing IE7 bug. A patch of using a blocking rule on customHTML fixes: navigator.userAgent matches RegEx ^.+ (.*MSIE [7-8].0; .*).*$
      • GTM iframe placed in <head> rather than <body> causing IE warning.
      • GTM.js added TWICE with the same dataLayer name causing gtm.dom conflicts.
  1. Human errors (or lack of GTM training):
    • setDomainName dataLayer not present (or added via jsmacro in GA classic)
      • mixing setDomainName=”www.clientdomain.com” & “clientdomain.com” which are different cookie domain hashes.
      • fallback value setDomainName=auto not enabled – causing setDomainName=undefined tracking fail!
    • default blankTracker name not used. Causing AddThis, ShareThis, Disqus, Livefyre, Optimizely, LiveChat to send GA UA-xxxxx-1 errors in GA classic.
    • dataLayer=[]; used in CustomHTML must be used to append, rather than override values. See this discussion here. Hence use dataLayer = window.dataLayer || []; dataLayer.push({“event”: “value”});
    • Hardcode gaq.push used rather than dataLayer.push within customHTML.
    • Hardcode UA-00000-1 used in customHTML rather than {{settings_ga_id}}
    • Typos in setting_ga_id default (or lookup table not used), thus migrations from Dev to Live break GA accountID.
    • default value entered for userId dataLayer rather than “undefined” or “” causing userId profile view to fail.
  2. Other less common issues
    • When using localCountryTrackers, the {{trackerName}} macro must be used in customHTML, otherwise GA will trigger UA-xxxxx-1 errors.
    • Local currency field not-set in ecommerce localTracker: ga(‘create’,'{{settings_ga_id}}’, {‘name’:’localCountryTracker’},’set’,’currencyCode’,'{{transactionCurrency}}’);
    • If using Content Experiments and cross-domain tracking ensure
      <script>_udn = “{{dataLayer.settings_ga_setDomainName}}”;</script> is added.
  3. Poor security planning on the Google Account :
    • Password easy to guess via brute force
    • Two-stage SMS authentication not enabled
    • HTML failsafe switch “blacklist”:[“customScripts”,”nonGoogleScripts”,”nonGoogleIframes”,”k”] not used.


More tips to avoid mistakes here:

jeffsauerjosh westqubit

0117 3361103