Cross Domain Tracking, Multiple Domains & You.

I don’t know if it’s due to the recent articles I’ve read concerning the quality of search results on Google or if my search queries have been inaccurate but lately it’s been hard for me to find what I need. For the past week I’ve been doing research for a client for my job on installing cross domain tracking and multiple domains per Google Analytics account. The client wants to be able to track the stats for all their domains in one profile, while splitting the stats up by each domains. The client also has a shopping cart/ecommerce solution on a separate domain which means we need to setup cross domain tracking so we can record visits to multiple sites as one. If the visitor goes to the client’s site through an ad then goes to the shopping cart, it will show the ad as the referral rather than the client’s site; which is how it would be shown if cross domain tracking is not setup and the cookie isn’t passed through the link or form post.

To achieve what the clients wants we would have to get either one Google Analytics number and install it on all their domains or have a separate Analytics number per domain and then one Analytics number that would be for all domains. I opted for the second method because, first, if the client wants to give access to one of the domains, they would give access only that specified one and not to all the profiles. Second, it is much simpler to do this method than to have one Google Analytics number and filter out all the domains correctly.

Roll Up Reporting

To get that, we would need to setup roll up reporting which isn’t mentioned in Google’s Help. The only article I found by Google in regards to this was on their blog. Unfortunately, it is not for the new asynchronous tracking so I had to do some more digging and found this post on the Google Analytics help forum that tells me exactly what I need to do. To do all this, we would need to get a tracking code for every domain then a master code for all domains and add the following to every domain:

<script type="text/javascript">
	var _gaq = _gaq || [];
	_gaq.push(['_setAccount', 'UA-XXXXXXXXX-A']);
	_gaq.push(['_setAllowLinker', true]);
	_gaq.push(['_setAllowHash', false]);
	_gaq.push(['_trackPageview']);
	_gaq.push(['t2._setAccount', 'UA-XXXXXXXXX-B']);
	_gaq.push(['t2._setAllowLinker', true]);
	_gaq.push(['t2._setAllowHash', false]);
	_gaq.push(['t2._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>

UA-XXXXXXXXX-A would be replaced with the tracking code (your Google Analytics number) for each individual site and UA-XXXXXXXXX-B would be replaced by the master code. So to clarify, the UA-XXXXXXXXX-A would be different for each site, but UA-XXXXXXXXX-B would be the same across all sites. _setAllowLinker and _setAllowHash are needed for cross domain tracking to work. _setAllowLinker allows for cookies to get passed across pages on different domains and _setAllowHash “turns off domain hashing which is critical for cross domain tracking or GA will reject your cookies integrity, and rewrite the cookie.” If for some reason, you had to add additional trackers, you can just copy the lines with t2 and replace with t3, t4, awesome or any variable you want.

Example (UA-XXXXXXXXX-C would be the new tracker for whatever reason):

<script type="text/javascript">
	var _gaq = _gaq || [];
	_gaq.push(['_setAccount', 'UA-XXXXXXXXX-A']);
	_gaq.push(['_setAllowLinker', true]);
	_gaq.push(['_setAllowHash', false]);
	_gaq.push(['_trackPageview']);
	_gaq.push(['t2._setAccount', 'UA-XXXXXXXXX-B']);
	_gaq.push(['t2._setAllowLinker', true]);
	_gaq.push(['t2._setAllowHash', false]);
	_gaq.push(['t2._trackPageview']);
	_gaq.push(['t3._setAccount', 'UA-XXXXXXXXX-C']);
	_gaq.push(['t3._setAllowLinker', true]);
	_gaq.push(['t3._setAllowHash', false]);
	_gaq.push(['t3._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>

Cross Domain Tracking

If you did setup the code earlier, to ensure that user information gets carried from domain1.com to domain2.com we would need to pass _link (for links) or _linkByPost (for forms) functions from the first to second domain. To set that up, any domain pointing to domain2.com from domain1.com would need to have this as the link.

<a href="http://domain2.com" onclick="_gaq.push(['_link', 'http://domain2.com']); return false;">domain2.com link</a>

If we were passing a form from domain1.com to domain2.com, the <form> tag would need to have the code below used. A common scenario for this would be an online store where the first domain would hold the actual store and the second domain would hold the shopping cart. When the customer goes from store to cart, it’s usually to checkout and usually using the POST method so we could need to push the visitor’s info to the new domain.

<form name="form" method="post" onsubmit="_gaq.push(['_linkByPost', this]);">

Using those methods, the user’s information would be correctly passed from one domain to another so in your stats you would see the original referrer that led them to the first domain and not the first domain as the referral.

Now what?

Doing the roll up reporting and cross domain tracking for our client should allow the following:

  1. We would have a separate profile per domain and then allow us to add additional profiles to each property for any kind of filtering we want.
  2. 2. All visitor’s information would be correctly passed from one domain to another domain so we wouldn’t have domain1.com as a referral for domain2.com.

If you have any questions, please leave a comment. I normally don’t do articles like this but this setup took me too long to find so hopefully it’ll be easier to find for you. If my explanation isn’t correct, please say so. The setup works for me and is accurate but my explanation might not be 100% correct.

  • http://www.optimisationbeacon.com/ Rob Kingston

    I loathe cross-domain tracking with a passion. There’s one easy fix that I found on Citricle’s site. It’s for aan ecommerce platform called NetSuite, but it should apply for most other sites with a similar setup (i.e.Two domain names – people land on one domain but no one lands on the other domain):

    http://www.citricle.com/blog/how-to-integrate-netsuite-with-google-analytics/

    I also wrote about it a bit on my site too.

    You may find some incompatibilities with Roll-up accounts and tracking custom variables – as I’ve found on other sites. Basically I’ve found that multiple trackers, cross-domain tracking and custom variables don’t play well together.

  • Anonymous

    I’ve been able to get it working for the most part, my only main issue now is if I have 5 domains linking to one domain (like five different stores going to a central checkout), there’s no way for me to find which site referred which visitor since the referral data is overwritten by the cross domain tracking. Only workaround so far is just to tag the URL itself and segment it out through advance segments.

  • http://twitter.com/robkingston Rob Kingston

    That sucks…

    Maybe you could modify the URLs sent to GA through _trackPageview.

    i.e.

    /store-1/checkout
    /store-2/checkout

    At least then you’ll be able to split them out into different profiles and look at goal funnels by store.

    If you’d like to look at Ecommerce for each site though, you’ll need to add strings based on the store for each transaction ID because (of course) Pageviews and Ecommerce both need to be filtered out seperately (I learned this the hard way).

  • Anonymous

    I should be able to track everything through the master account which is the UA number on everysite and then use funnels from there, but I don’t think your method would work if I was looking at the domain with the checkout since the top content only shows the content for the domain it’s on right? Does cross domain tracking push data like what pages they were on at the previous domain onto the new one?

    Ex: domain1.com I went to page1.html then cart.html then from cart.html I went to domain2.com (checkout). If I pushed the cookie data with _linkByPost would I be able to see page1.html in domain2.com?

  • http://adworkmedia.com David

    Awesome explanation, that really helped me better understand cross domain and multiple UA tracking.  Thanks Chris.

  • Michael Lommel

    “…there’s no way for me to find which site referred which visitor since the referral data is overwritten by the cross domain tracking.” 

    Chris, does this help: http://code.google.com/apis/analytics/docs/tracking/gaTrackingSite.html#profilesKeySee bullet point “Modify your cross-domain profile with a filter to show the full domain in your content reports.”

  • Jan

    Hi Chris,
    Any idea how can I track onclick events in roll up report. The issue I’m having is that when I use an onclick event like this

    onclick=”_gaq.push(['_trackPageview', '/twitterclick']);” then I will see goal recorded in one of the 2 accounts, but never in booth.

    Regards Jan

  • http://a.trendyname.org Chris

    You’d have to do something like onclick=”_gaq.push(['t2._trackPageview','/twitterclick']);_gaq.push(['_trackPageview','/twitterclick']);” where t2 is the second account (similar to how I define t2,t3 in the post above). Let me know if it works.

  • Jan

    Chris thanks, it worked. One more question regarding ecommerce tracking code when using roll up reporting. Do I need to place 2 ecommerce tracking codes on order confirmation page?

    One would look like this?
    _gaq.push(['_setAccount', 'UA-XXXXX-6']);
      _gaq.push(['_trackPageview']);
      _gaq.push(['_addTrans'

    "rest of the code goes here"

    The roll up would like this?_gaq.push(['rollup_setAccount', 'UA-XXXXX-7']);
      _gaq.push(['rollup_trackPageview']);
      _gaq.push([‘rollup_addTrans’

    “rest of the code goes here”

    Thanks again. Jan