How To Track Sub-Domains / Cross-Domains in Google Analytics

First of all, let me explain why in Google Analytics you need to do some configurations to track sub-domains / cross-domains.

Google Analytics does not do this by default, thus whenever you’re on sub1.domain.com and you go to sub2.domain.com, Google Analytics will record this as a referral rather than maintaining the same session and the same campaign information. If you’re running e-commerce tracking and you use sub-domains during the e-commerce process, this will totally screw up your reports as it will attribute all transactions to referrals (from your own site) and you will have no idea how your other online marketing campaigns (i.e. direct, organic, cpc) are performing.

Sub-Domain Tracking

This one is fairly easy. The method you need to use is _setDomainName().

Google utma cookie

The _setDomainName() method sets the Google cookies to the domain name string parameter that it is given, otherwise it automatically resolves the domain name from the location object in the DOM if no parameter is given. This means that on sub-domains, the cookies will be set to separate sub-domains.

So to configure Google Analytics to set the cookies to the same domain name, simply use the domain name as the string parameter for the _setDomainName() method.

E.g. If I have a website called sub1.dannytalk.com and sub2.dannytalk.com, I would use _setDomainName(‘dannytalk.com’) throughout all my pages (sub-domains and main domain).

<script type="text/javascript">
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
</script>

<script type="text/javascript">
var pageTracker = _gat._getTracker("UA-xxxxxx-x"); // replace this with your own account number
pageTracker._setDomainName("dannytalk.com");
pageTracker._trackPageview();
</script>

The Google API officially states to use the period at the start of the domain name. I have tried with and without and it seems to work fine but I prefer without period (looks nicer).

Once you’ve done this, Google Analytics should record all visits to these sub-domains as the same visit, maintaining the same campaign information. However, in your reports,you won’t be able to tell which request URI came from which sub-domain as the domain name is stripped out from the reports.

In addition, if you have two sub-domains that have the same page name (i.e. index.html), then Google Analytics will combine these two into one which will artificially inflate your page statistics.

A simple way around this is to implement what I call a sub-domain visibility filter which will prefix your request URI’s with the domain name. This will help you differentiate the pages as well as avoid inflating the page statistics.

sub-domain-visibility-filter

Cross Domain Tracking

This one is a bit trickier as it involves sending your cookies across to the 3rd party domain so that all your cookie information is maintained throughout. A pre-condition to this is that you have permission to insert Google Analytics code onto the 3rd party domain. 3rd party domains such as Paypal won’t let you insert third party codes in the checkout process.

Assuming that you want to track from www.mydomain.com across to www.thirdpartydomain.com, on www.mydomain.com, on the page where you’ll be linking to the 3rd party domain use,

<script type="text/javascript">
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
</script>

<script type="text/javascript">
var pageTracker = _gat._getTracker("UA-xxxxxx-x"); // replace this with your own account number
pageTracker._setDomainName("mydomain.com"); // optional if you have sub-domains (refer to sub-domain tracking above)
pageTracker._setAllowLinker(true);
pageTracker._setAllowHash(false);
pageTracker._trackPageview();
</script>

The _setAllowLinker() method activates _link() and _linkByPost() when you’re sending cookie information across to the 3rd party domain and the _setAllowHash() method determines whether Google Analytics sets the unique domain hash to the cookie for integrity checking. You set the cookie integrity check to false because you’re tracking cross-domain, not within the same domain (which will fail the check).

If you’ve ever seen the ga.js file, you’ll find out that it is super cryptic and backwards engineering won’t be that easy. However, the _gat.t() _gat.s() method generates the unique hash for a domain. ([edit date=090923] Note: ga.js has recently updated the domain hash function to be s() instead of t()).

domain-hash-function

You will see that 51787068 is the number that corresponds to the number before the first period of my utma cookie (see cookie screenshot above). This is how Google Analytics performs the domain hash integrity check.

On www.thirdpartydomain.com pages where you want to keep maintain the same visit,

<script type="text/javascript">
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
</script>

<script type="text/javascript">
var pageTracker = _gat._getTracker("UA-xxxxxx-x"); // replace this with your own account number
pageTracker._setDomainName("mydomain.com"); // optional if you have sub-domains (refer to sub-domain tracking above)
pageTracker._setAllowLinker(true);
pageTracker._setAllowHash(false);
pageTracker._trackPageview();
</script>

Linking The Cookies

Ok, so now you’ve got the Google Analytics configuration all set up for cross-domain tracking. So now is the time to actually send the cookie information across to the 3rd party website.

If you go to www.thirdpartydomain.com from www.mydomain.com from an anchor link, you will need to use the _link() method.

Third Party Domain

The _link() method will append the cookie information as query string parameters across to the 3rd party domain which Google Analytics will read and recreate the identical cookies.

If you go to www.thirdpartydomain.com from www.mydomain.com from form, you will need to use the _linkByPost() method.

<form action="http://www.thirdpartydomain.com" method="post" name="testform">...</form>

Similar to the _link() method, the _linkByPost() method will include the form parameters into the query string as well.

Debugging

Here are some tips to making sure your sub-domain / cross-domain tracking is working properly.

  • Check the Google Analytics reports to confirm what you’re expecting.
  • When cross-domain tracking, make sure you check the cookies of each step to make sure they’re the same cookies. Make sure you delete the cookies on both domains before doing this.
  • Check the cookie values in the query string to see if they’re the same.
  • You shouldn’t be getting two sets of Google cookies (i.e. duplicate utma, utmb, utmc, utmz cookies). If you are, most likely some pages don’t have the  _setDomainName() method (if you are using it).

I hope these instructions and examples help you with your tracking!

21 Comments on "How To Track Sub-Domains / Cross-Domains in Google Analytics"



  1. Hi Danny

    just a few queries regarding subdomain filters:
    i have setup filter for a site with
    example.com
    subdomain1.example.com
    subdomain2.example.com

    Have created a master profile and individual profile for each of the sub domains. have also applied an included filter and a sub domain filter (similar to yours) to each of the sub domains. In the reporting, i am getting errors with example.com/subdomain1.com shown the ‘visit this link’ and also overlay links.

    if you can help out, that would be awesome :)

    thanks heaps in advance

    Reply

    1. Hi Mike,

      You’ll need to let me know how did you do the filters. Seems weird that you’re getting double hostnames in the filter unless subdomain1.com is set as your request URI which you could’ve done if you did _trackPageview(‘/subdomain1.com’).

      Reply

    2. Hi Mike,

      I wouldn’t use the overlay links in Google Analytics. Not very accurate as the overlay is not based on the actual link but the href which won’t do what you’re expecting.

      What kind of errors are you getting? Is it forming the request URI correct in the content reports (/hostname/request uri)?

      Reply

  2. Hi Danny,

    Thanks for this.

    Just a note on what you said here:

    You shouldn’t be getting two sets of Google cookies (i.e. duplicate utma, utmb, utmc, utmz cookies). If you are, most likely some pages don’t have the _setDomainName() method (if you are using it).

    Surely for cross-domain tracking, all these cookies _should_ be the same??

    Reply

  3. Thanks for this post it clears up a few things. Much appreciated.
    I’m using the pageTracker._setDomainName() to make sure my cookies are being shared between http://www.example.com and secure.example.com, but for some reason the values still seem to change a lot of the time. One site is http and the other is https, should that matter? Thanks.

    Reply

    1. Hi Chris,

      Will need to find out exactly what you’re doing but if you’re doing sub-domain tracking, you need to use _setDomainName(‘.example.com’). The https and http issue shouldn’t matter.

      What do you mean by values change a lot? What values are these?

      Reply

  4. It looks like G’s modified the gatc.js – now the hash method is _gat.s(‘mydomain.com’) – shoutout to JS beautifier at jsbeautifier.org

    cheers

    Jamie

    Reply

  5. Hi Danny,

    Cool post!

    I’m in the process of setting up a collection of subdomains.

    Can you tell me how your walkThru here relates to Googles own GA subdomain tracking shown here…?

    http://www.google.com/support/googleanalytics/bin/answer.py?hl=en&answer=55524

    Is yours an alternative way, or an additional benefit?

    Also, I want to be able to compare traffic / goals etc from the subdomains with those from the main site – but also have as much visibility of the subdomain visitors as possible… is it considered better to track them all in the same GA profile, or set up new ones for the subdomains?

    Thanks

    Reply

    1. Hi Charles,

      Sorry for the late reply. Been busy :S

      My sub-domain tracking example is the same as Google’s. If you look at their filter, I’ve just got my A and B fields the other way around but essentially it’s the same.

      Best to consolidate all traffic/goal data into 1 main profile and create another profile to capture all the traffic/goal data relating to a specific sub-domain using an include filter.

      Reply

  6. Nice post.
    Some doubts about how does it appear in report?
    For example, if you have a visit from your dannytalk.com, and the same visit goes also to blog.dannytalk.com.
    As it is made to set the same cookie, it will count only 1 visit to your report correct? But at hostname visits can you expect 1 visit from dannytalk.com and 1 at blog.dannytalk.com? or it only count at dannytalk.com?

    Reply

    1. Yes, it will only count as one visit if you visit the sub-domain as well.

      I think you’re talking about pageviews and yes, it will count 1 pageview on dannytalk.com and another on blog.dannytalk.com as the request URI’s will be prefixed with the hostnames.

      Reply

      1. Thanks Danny,

        in fact i was talking about Visitor > Network Properties > Hostnames report. As i sum visits from each hostname, it is the same as total visits, so does it only represent visits that starts at that hostname?
        For the example above, at Hostname report, it will only appear 1 visit to http://www.dannytalk.com and zero to blog.dannytalk.com, but as you mention, i can find visits to page blog.dannytalk.com/ at Top Content report. Is that correct?

        thanks again.

        Reply

        1. I still believe you will be able to see hostnames as the filter relies on the hostname field. This implementation only affects how the cookies are set to the domain.

          So it should still show dannytalk.com and blog.dannytalk.com and yes, you will still be able to see the visits in the content report if you’ve applied the sub-domain visibility filter. Otherwise, it will get consolidated if they have the same request URI.

          Reply


  7. Hi, great post.

    Can you explain why on the 3rd party site
    the pageTracker._setDomainName is set to – (“none”); ?

    Isn’t the point by setting the doamin name is so that the visit will be considered as same visit for both domains?

    thanks..

    Reply

    1. What is considered the same visit is the utm cookies, not which domain the cookies are set to.

      The link() and linkByPost() method ensures that your original cookies are maintained on the 3rd party site.

      Reply

  8. Cool post. This is something I have been talking about quite a lot on my blog as I am in the middle of some large implementations around ecommerce sites running across 30 sub domains. One problem I have is, even though its set up correct, I am still seeing self referrals from sub domains. I have changed my domain in setDomainName to remove the period i.e. subdomain.com to see if this makes a difference.

    Reply

    1. kieran: I think I’ve encountered a similar situation before as well. If you’ve implemented sub-domain tracking mid-way and you’ve already got visitors who have their campaign medium as a self-referral, future ‘direct’ visits by them will not overwrite their existing Google cookies which means your reports will still show self-referrals.

      This should decrease over time (6 months from sub-domain tracking implementation to be precise) and you can treat these pretty much as direct visits.

      Reply

Leave a Reply to danny Cancel reply

Your email address will not be published. Required fields are marked *