Cross Domain Tracking in Google Analytics

Posted by on Tue, Feb 1, 2011
Filed Under | Analytics, Google Analytics


Cross Domain Tracking Overview

UPDATE: The recommended way that cross-domain tracking is performed has changed since this post was originally written. Google Analytics code no longer enforces the domain hash, so you no longer have to use _gaq.push(['_setAllowHash', false]);

Cross domain tracking is required anytime you want to track a single GA session between multiple domains that you control.

A common example is a 3rd party checkout system that resides on a different domain.  For the purpose of keeping our examples consistent throughout this blog post, let’s fictitiously  assume that your scenario involves your primary domain (www.primarydomain.com) and a 3rd party checkout provider (www.3rdpartycheckout.com).

Additionally, all code referenced in this document is using the asynchronous syntax.  It is important to note that if you have not yet migrated over to the asynchronous format that the example code provided will not work as is.

Note: If you can get your provider to place their system as an alias onto a subdomain of your regular domain, this simplifies the setup process immensely. Also, users won’t look at the URL in their browser and wonder what site they are on (especially in cases where you can’t control the look & feel).

Impact of Not Using Cross Domain Tracking

If you don’t use cross-domain tracking or you have it improperly configured, you’ll end up with meaningless data that shows self-referrers in the visit reports and a lack of proper attribution towards your conversion points.  As a visitor moves from your primary domain to the other, they will start a brand new session in Google Analytics.

To understand why this happens, you must first understand how Google Analytics works.  Google Analytics uses first-party cookies that are attached to the visitor’s browser.  Those cookies contain data about when the visitor last visited the site, what page it was, and a variety of other data.  When the user clicks between pages or comes back at a later date, the ga.js javascript looks for the existence of that first party cookie.  If it doesn’t find a cookie, then it views that visitor as a brand new visitor (that has NEVER been to your site).  First party cookies are great (the best type), but for security reasons, they do not transfer between domains.  The first party cookie is linked directly to the domain that set it and will not be accessible by any other domain.

If the visitor views a few pages on www.primarydomain.com and then clicks a link or submits a form that takes them to www.3rdpartycheckout.com, the ga.js script looks for a first party cookie tied to www.3rdpartycheckout.com.  Without having cross-domain tracking properly configured, it will not find a cookie and will start a brand new GA visit as a new visitor.  Now, of course, if you’ve had this problem for a while, you’ll see returning visitors because they’ve visited the www.3rdpartycheckout.com in the past.

As you can see, this is a HUGE problem.  If a visitor clicks an ad or performs and organic search and ends up viewing a page on the www.3rdpartycheckout.com after viewing pages on www.primarydomain.com, you lose ALL data about how that user arrived and the complete picture of what they did.  If they end up converting, you will only know that they came from www.primarydomain.com (which is not helpful at all).

Solution for Cross Domain Tracking

To properly track a visitor as they move from www.primarydomain.com to www.3rdpartycheckout.com, you will need to make code modifications to the code on both sites.

Steps & Code for www.primarydomain.com:

  1. On all pages of the site, set _setAllowLinker to true via _gaq.push(['_setAllowLinker', true]);
    This enables domain linking and allows the use of _link() and _linkByPost().
  2. On all pages of the site, turn off domain hashing via _gaq.push(['_setAllowHash', false]);
    Domain hashing needs to be turned off to allow the cookie to be properly read by the www.3rdpartycheckout.com ga.js script.
  3. On all pages of the site, set the current domain name via _gaq.push(['_setDomainName', '.primarydomain.com']);
    Note that there is a leading ‘.’
  4. Send the current GA cookies over to the domain via parameters in the link. Google makes this quite easy by using either _link() or _linkByPost() functions in your code.  Both will transfer the cookies from one domain to the querystring of the resulting link.  The ga.js script on the other domain landing page will detect the parameters in the URL and assemble a new GA cookie that references the same browsing session.

Here’s the full tracking code snippet along with an example link and form that pushes the GA cookies over to the other domain:

<script type="text/javascript">
    var _gaq = _gaq || [];
    _gaq.push(['_setAccount', 'UA-9999999-9']);
    _gaq.push(['_setAllowLinker', true]);
    _gaq.push(['_setDomainName', '.primarydomain.com']);
    _gaq.push(['_setAllowHash', false]);
    _gaq.push(['_trackPageview']);

    (function() {
        var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
        ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
        var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
    })();

</script>
...
<a href="http://www.3rdpartycheckout.com/checkout.html" onclick="_gaq.push(['_link', this.href]);return false;">Checkout Now!</a>
...
<form name="formName" method="post" onsubmit="_gaq.push(['_linkByPost', this]);">
</form>

Steps & Code for www.3rdpartycheckout.com:

  1. On all pages of the site, set _setAllowLinker to true via _gaq.push(['_setAllowLinker', true]);
  2. On all pages of the site, set _setDomainName to ‘none’ via _gaq.push(['_setDomainName', 'none']);
    Note: When you use none as the domain name, it automatically turns off domain hashing.
  3. Use _link() and _linkByPost() to send GA cookies back to the www.primarydomain.com if links exist to bring the user back.  This is especially important if the initial landing page can be on the www.3rdpartycheckout.com domain.

Here’s the full tracking code snippet along with an example link and form that pushes the GA cookies over to the other domain:

<script type="text/javascript">
    var _gaq = _gaq || [];
    _gaq.push(['_setAccount', 'UA-9999999-9']);
    _gaq.push(['_setAllowLinker', true]);
    _gaq.push(['_setDomainName', 'none']);
    _gaq.push(['_trackPageview']);

    (function() {
        var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
        ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
        var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
    })();

</script>
...
<a href="http://www.primarydomain.com/products/" onclick="_gaq.push(['_link', this.href]);return false;">Continue Shopping</a>
...
<form name="formName" method="post" onsubmit="_gaq.push(['_linkByPost', this]);">
</form>

Conclusion

If properly setup, cross domain tracking will maintain the proper referral and other session data for visitors on your site.  You will begin to accurately track bounce rates, conversion sources, and other metrics.

The example code we’ve provided satisfies the most common cross-domain setup.  There are specific circumstances and many variables that warrant different code and strategy.

Whether you need Google Analytics Help to check to ensure that the code you have in place is working correctly or you need help setting up tracking in another situation, we can help. Give us a call at 1(888)252-7866.

Enjoy this post?

Join the discussion below, subscribe to our RSS feed or share it on the web.

This post was written by:

has written 30 posts on the Web Analytics Blog.

Joe is the Analytics Director and a Partner at Blast Analytics & Marketing. He understands Google Analytics like nobody else and is a master of many programming languages.

Add Joe to your circles on Google+


Tags: ,
  • Pingback: Tweets that mention Cross Domain Tracking in Google Analytics | Blast Advanced Media -- Topsy.com

  • Breklin

    Thank you for this very clear and useful demo. Quick question, though. Are the GA profile IDs supposed to be the same for the secondary domain as they are for the first? That is where I am stuck.

  • http://www.blastam.com/broadcast Blast Advanced Media

    Great; glad you enjoyed the article! Yes, the GA UA-# should be the same for both the primary and secondary domain.

  • http://twitter.com/joaocorreia Joao Correia

    Hello Breklin,

    What I usually do is setup a profile per domain and filter just that domain traffic by applying a filter (custom filter: Include Hostname http://www.domain.com). I use the same GATC on all domains (multiple top-level domains).
    On an aditional profile you can gather all domains traffic by not applying any filter. Don’t forget to call the _link() method when linking between domains, otherwise you will get wrong visitors and referrals data.

  • Keithnoone23

    Looks like an excellent post. Well laid out and easy to understand. I am going to give this a shot. Wish me luck!

  • Keithnoone23

    Ok so I tried but it didnt work fully. The query parameters werent being passed. I was looking at the google conversion videos and they said to do this?

    var _gaq = _gaq || [];
    _gaq.push(['_setAccount', 'UA-21687229-1']);
    _gaq.push(['_setDomainName', 'none']);
    _gaq.push(['_setAllowLInker', true]);
    _gaq.push(['_trackPageview']);
    ….

    Also I am linking through links that have an image I am trying:

    title=”click for the shop”>

    Any help with this is much appreciated.

  • http://www.blastam.com/broadcast Blast Advanced Media

    Hi Keith,

    Change _setAllowLInker to _setAllowLinker (lowercase i).

    If you reply with your URL or email joe at blastam.com with the URL, I will be happy to take a look at your implementation and advise further.

    If you use the onclick=”_gaq.push(['_link',this.href]);return false;” and there is an href value on the link tag that surrounds the image, it should correctly pass the parameters.

    Thanks,
    Joe

  • http://twitter.com/AnalyticsNinja Yehoshua Coren

    Hi Joe,

    There are some improvements that can be made to your code sample.

        var _gaq = _gaq || [];
        _gaq.push(['_setAccount', 'UA-9999999-9']);
        _gaq.push(['_setAllowLinker', true]);
        _gaq.push(['_setDomainName', '.primarydomain.com']); //unnessary
        _gaq.push(['_setAllowHash', false]);
        _gaq.push(['_trackPageview']);

      

    Checkout Now!

    1). There is no need to invoke _setDomainName. Your post is ab
    out cross domain tracking, not subdomain tracking. The cookies will automatically write to the domain they are on.

    2). If one does call _setDomainName, then the leading period is not necessary. It is only required to track sub-subdomains. (
    Just a side note).

    **On the 3rd party site:

        var _gaq = _gaq || [];
        _gaq.push(['_setAccount', 'UA-9999999-9']);
        _gaq.push(['_setAllowLinker', true]);
        _gaq.push(['_setDomainName', 'none']); // use _setAllowHash to false instead
        _gaq.push(['_trackPageview']);

        …
    Continue Shopping
    1). Here too, the call to _setDomainName should really be to _setAllowHash. While _setDomainName to none does indeed turn of domain hashing, it also writes the cookies to the explicit domain name. It is better to simply turn off domain hashing with _setAllowHash. _setDomainName doesn’t have any purpose for cross-domain tracking.Best,Yehoshua

  • http://twitter.com/mrPerezMarc Marc Perez

       _gaq.push(['_setAllowHash', false]); has been deprecated

  • Michael

    How am I supposed to push the Analytics cookies over to the 3rd party page if the 3rd party page is displayed within an iframe?

  • http://www.blastam.com Joe Christopher

    Hi Michael,

    This link should help you out: http://code.google.com/apis/analytics/docs/tracking/gaTrackingSite.html#trackingIFrames

    You’ll have to modify the iframe src attribute.

    There are a lot of different and unique situations when it comes to iframes, so if you can share more information, that would be helpful.

    Thanks,
    Joe

  • Gabe Kassel

    this is great – way better than google’s own documentation

    i’m struggling on the profile setup side. i made two profiles with filters to filter out traffic on each others domain (site + 3rd party ecommerce store) but all profiles (site, ecomm, default) all show 100% of the cumulative traffic….?

    a second question, how do i use cross-domain with multiple GA profiles? i have two sites that funnel into the same ecomm store, for example.

    thanks!

  • http://www.blastam.com Joe Christopher

     Hi Gabe,

    It sounds like you may not be using a regular expression to filter against the hostname.  So mysite.com becomes ^mysite.com$ in the filter as a regular expression.  That is just a guess though as to the issue. 

    For your second question, you need to make it dynamic to only load a specific GA UA-# on the store.  Need more information on the setup/scenario though to advise further.

    Thanks,
    Joe

  • Cory

    Hi Joe,
    Great post.  I’ve been successful setting up cross-_sub_domain tracking like this:

    http://www.example.com sub.example.com

    But I also do this:

    http://www.example.com/hello contains an iframe of a WordPress form from http://www.example2.com/form-1

    So, if someone clicks an ad in my Adwords campaign, they land on http://www.example.com/hello and fill out the form through the iframe on http://www.example2.com/form-1...

    How do I best code to capture that conversion?

    Here’s what I have on http://www.example.com:

    _gaq.push(['_setAccount', 'UA-999999999-1']);_gaq.push(['_setDomainName', 'example.com']);_gaq.push(['_addIgnoredRef', 'example.com']);_gaq.push(['_trackPageview']); 

    You said to alter the iframe src above but I get lost on the Google “Tracking Across iFrames” instructions.  What else should I do?

    Where do I put this?
    _gaq.push(function() {
      var pageTracker = _gat._getTrackerByName();
      var iframe = document.getElementById(‘myIFrame’);
      iframe.src = pageTracker._getLinkerUrl(‘http://www.my-example-iframecontent.com/’);});

    Thank you!

  • http://www.blastam.com Joe Christopher

    Hi Cory,

    You’ll want to place your code that modifies the iframe.src either in a document ready function or immediately below the iframe tag (recommended). This should append the cross domain cookies onto the iframe.

    On both domains, you should use _gaq.push(['_setAllowLinker',true]); to enable cross-domain.

    To complicate things though, in IE the iframe won’t set any GA cookies, which is a big problem. To get around this, you’ll need to setup a privacy via P3P. There is a section in the doc that explains this.

    Hope that helps!
    Joe

  • http://www.blastam.com Joe Christopher

    @3e465e0e74aa9aed70bf13057e0babad:disqus All sites should share the same GA tracking code configuration. To configure a filter, go to Admin > Profles > Filters and then add a filter. Here’s a screenshot if you only wanted to include m.domain.com

  • carmen

    Hi Joe,

    Awesome post. thanks for that. but im still not sure what to do in my case.
    I have one domain http://www.xy.com which sells items, but transcation will be on another domain http://www.zz.com. so this would be no problem. but the domain zz.com sells items itselfs.

    what i need to have is the following: one google account with only traffic and sales from domain xy.com (including the sales passed to zz.com), an another account with only traffic and sales from zz.com (no sales passed from xy.com).

    is this possible?

    thanks in advance,

    br
    carmen

  • http://www.blastam.com Joe Christopher

    @a1ec93106b58329b7590317215c24319:disqus It is possible assuming you have control of zz.com or zz.com is willing to work with you to accomplish this. It is tricky. At a high level, you’d have to cookie users coming in from xy.com to zz.com (based on referrer data) and then if that cookie exists, fire the proper GA tracking code. Otherwise, if a user came to zz.com from a non xy.com source, it would fire the standard GA tracking code on zz.com.

  • http://www.blastam.com Joe Christopher

    @a02c1a76c8ac542744216845f9eb7d7a:disqus You no longer need to use the _setDomainName ‘none’.

  • http://www.blastam.com Joe Christopher

    In GA there would be two different sessions between the separate UA-#s. The GA cookies though would still transfer between which means that the original source data should be intact.

  • http://twitter.com/something4ken Kenold Beauplan

    why do you use _gaq.push(['_setDomainName', '.primarydomain.com']); on domain1? is it optional?

  • http://joaocorreia.pt/ João Correia

    Hi Berrega,

    Code needs to be the same to maintain domain hash, present in GA cookie. Otherwise cookies will be invalid and GA would assume new visitors for every page.

  • nirzari

    What if the landing page already has its own parameter ? I tried it and got that the parameters from the code appended by . (dot) after the landing page’s own parameters. This results as a broken link. Please help asap.

  • http://twitter.com/ndemi Ewa

    There is no need to use _gaq.push(['_setAllowHash', false]); right now.

  • Anat

    Hi Joe, thanks for the great article!

    I am looking for a solution, I’m not sure GA cross-domain can help me with. Thought you might know…

    My software supplies a Javascript code snippet to blogs to create related posts content recommendations at the end of the article.

    I would like to use a 3rd party tracking tool, like GA, to track the number of pageviews my code is located on. I can’t use GA cross-domain, because I am afraid of creating conflicts with the tracking of my hosting page.

    Got any idea what service I should use?

    Thanks!

    Anat

  • SoccerZortz

    I don’t see how you can set the GA UA-# the same on both sites. Currently, we have a different UA-# on the secondary domain. If I change that one to be the same as the primary domain, isn’t it going to break everything for the Google property we have set up for the secondary domain? Thanks in advance.

  • http://www.muschamp.ca/ Muskie

    This is probably the best explination on why and how to do this I’ve found. Of course if you want to use Goals or e-Commerce you have to do even more as I’m learning. In the iFramed content on the 3rd Party website you need to get them to push an event to the passed in cookie / Google analytics code. I’m looking for a good example of this, I may have to build one…



Goal Driven Online Marketing & Analytics
Copyright © 1999-2013 Blast Analytics & Marketing