Cross-Domain Tracking 101

Subscribe to our monthly newsletter to get the latest updates in your inbox

So, you’re a large company that owns multiple domains and wants to report on company-wide performance and understand attribution better? Well, look no further! Luckily, this isn’t the first time we’ve solved for this solution. In this article, we’ll talk about:
  • Why cross-domain tracking is important
  • How to implement cross-domain tracking (in GTM, hard-coded GA, or gtag.js)
  • Implications of cross-domain tracking in GA reports
Note, this article explains an implementation for when the root domains a user traveling across are different. This does not address for when a user travels across subdomains for the same root domain.  

Why cross-domain tracking is important

Let’s consider the following path. Tanya goes to Google.com and searches for "domain 1" and clicks on this paid search ad to get to domain1.com.     Tanya then clicks on a link from domain1.com to domain2.com.     For a case where each domain is sending to a different tracking ID, but the data in both source properties are forwarded to a 360 rollup property, what happens?     How many sessions and users show up in the rollup property? What sources and mediums will be reported? If you guessed “2 sessions and 2 users with 1 session coming from google / cpc and 1 session coming from domain1.com / referral,” then you’re absolutely right! Google Analytics determines “users” based on a 1st party cookie (_ga) that is created for a user that visits your site for the first time. There are many things to note about a 1st party cookie (e.g. browser-specific, device-specific), but for the purposes of cross-domain tracking, the important call-out is that the “user” is set at the root domain . When Tanya navigated to domain2.com , a new _ga cookie was created, creating a new user that started a new session with new attribution. Well, that’s no good. How do we know this is the same person and give credit to the paid search campaign that drove Tanya to both of these brands?  

Implementing Cross-Domain Tracking

To do this, there are 3 things we need to accomplish. We’ll talk through what that looks like in a GTM implementation using analytics.js, hard-coded implementation using analytics.js, and a gtag.js implementation. In a nutshell:
  1. Tell Google Analytics to allow domains to be linked to one another
  2. Explicitly tell Google Analytics which domains need to be linked
  3. Conduct Quality Assurance to ensure this works
 
  1. Tell Google Analytics to allow domains to be linked to each other
  • With analytics.js via GTM
    • In your Universal Analytics pageview tag, update your Fields to Set like below. This needs to be done in both containers.
   
  • With hard-coded analytics.js
    • Update your tracking snippet like below. This needs to be done for both snippets on both domains.
 
<!-- Google Analytics -->
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');


ga('create', 'UA-XXXXX-Y', 'auto', {'allowLinker': true});
ga('require', 'linker');
ga('send', 'pageview');
</script>
<!-- End Google Analytics -->
 
  • With Gtag.js
    • Update your tracking snippet like below. This needs to be done for both snippets on both domains.
 
<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=GA_TRACKING_ID"></script>
<script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());

gtag('config', 'GA_TRACKING_ID', {
  'linker': {
    'accept_incoming': true
  }
});

</script>
 
  1. Explicitly tell Google Analytics which domains need to be linked
  • With analytics.js via GTM
    • Option 1: In the Auto-link Domains field, provide the root domains in a comma-separated list for both GTM containers for the respective domains to be linked.
   
    • Option 2: If there is a long list of domains, consider creating a Custom JavaScript variable that stores the list of domains in an array. Reference that variable in the Auto-link Domains field.
   
  • With hard-coded analytics.js
    • Update your tracking snippet like below. This needs to be done for both snippets on both domains for the ones that need to be linked.
 
<!-- Google Analytics -->
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');

ga('create', 'UA-XXXXX-Y', 'auto', {'allowLinker': true});
ga('require', 'linker');
ga('linker:autoLink', ['domain2.com, domain3.com']);
ga('send', 'pageview');
</script>

<!-- End Google Analytics -->
 
  • With gtag.js
    • Update your tracking snippet like below. This needs to be done for both snippets on both domains for the ones that need to be linked.
 
<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=GA_TRACKING_ID"></script>
<script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());

gtag('config', 'GA_TRACKING_ID', {
  'linker': {
    'domains': ['domain2.com, dmomain3.com'],
    'accept_incoming': true
  }
});

</script>
 
  1. Conduct Quality Assurance to ensure this works

With either GTM Preview turned on or in a staging environment where this is implemented:

  1. Start recording your session with Tag Assistant.
  2. Navigate to domain1.com and decorate your URL with custom UTM parameters for testing (e.g. ?utm_source=catsmeow&utm_medium=catspurr)
  3. Check the value of your _ga cookie (either in Dev Tools > Security or with a Chrome plugin like Edit This Cookie).
  4. Click on a link that goes to a different domain.
  5. Check your URL. Did the query parameter of _ga get appended to it?
   
  1. Check your _ga cookie. Did it stay the same?
  2. End your recording and view your results in the “Google Analytics Report” tab.
  If your results look like below, with 1 session and 1 user across 2 pages coming from 1 source/medium, then congratulations, cross-domain tracking has successfully been implemented!    

Implications of cross-domain tracking in GA reports

Conceptually, implementing cross-domain tracking is a no-brainer. However, if cross-domain tracking wasn’t a part of the implementation since the beginning, it makes the decision to do this a little harder as it does impact what your data looks like.
  • If data for domain1.com and domain2.com are sending to the same property, sessions and users will go down.
    • This is a good thing since the numbers will be more accurate. However, since the numbers go down, often times explanation to the wider team is required.
  • If data for domain1.com and domain2.com are sending to the same property, referral traffic will go down.
    • Again, this is good because we’ll be able to see which channels are really driving traffic. However, some stakeholders may be used to measuring cross-site traffic using referral traffic so thorough communication and education need to occur when updating the implementation. We recommend implementing a session-scoped custom dimension of "Full Referring Hostname" to send to GA to support this type of cross-site measurement reporting.
  • If data for domain1.com and domain2.com are sending to different properties, then this implementation doesn’t matter. If we exported data from each domain into a CSV and combined them, the result would be 2 sessions and 2 users with 1 session coming from google / cpc and 1 coming from domain1.com / referral. This is because the data lives separately.
    • However, if these separate properties were configured to point to a 360 Rollup, then this implementation does matter and the solutions for unified sessions and true attribution work

For more resources: