The ROI Revolution Blog

Google Analytics Subdomain Tracking

January 5, 2011

submarine.jpgIf you do a quick search on "Google Analytics Subdomain Tracking", you may have noticed that many of the top results are either woefully out of date or rather confusing. The purpose of this post is to provide my recommendations for Google Analytics subdomain tracking as of the current version of the asynchronous Google Analytics Tracking Code.

Currently there's no specific article on Google Code dedicated to Google Analytics subdomain tracking. The closest is this, which recommends the following:

//Tracking code customizations only
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-12345-1']);
_gaq.push(['_setDomainName', '.example-petstore.com']);
_gaq.push(['_setAllowHash', false]);
_gaq.push(['_trackPageview']);

I propose that instead, for the vast majority of sites with subdomains, you should use the following:

//Tracking code customizations only
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-12345-1']);
_gaq.push(['_setDomainName', 'example-petstore.com']);
_gaq.push(['_addIgnoredRef', 'example-petstore.com']);
_gaq.push(['_trackPageview']);

So what's wrong with the code recommended on Google Code? It turns out there are three issues with the code that cause unnecessary problems:

1. Turn off hashing is bad.

Turning off the hash, either by ['_setAllowHash', false] or ['_setDomainName', 'none'], is necessary for cross-domain tracking to work correctly with Google Analytics. It's an unfortunate necessity, however, because domain hashing is actually quite useful.

By default, a script cannot identify the domain of a cookie; this information isn't available unless it's part of the cookie name or value itself. Including the hash provides that information so that the Google Analytics Code can read the correct set of cookies in situations where there might be more than one set.

Turning off the hash mean the Google Analytics Tracking Code has no way to tell which set of cookies is the right set. Most of the time there is only one set of cookies, so it's not that big of a deal.

But if you were previously using Google Analytics without subdomain tracking, then you may end up with two sets of cookies for return visitors: one set created by your old code, and one created by your new code. This happens most often on subdomains, but could also happen on your main domain if you use ['_setDomainName', 'none'] instead of ['_setAllowHash', false].

It's also possible that instead of creating two sets of cookies, your new Google Analytics Tracking Code will destroy the cookies from your old Google Analytics Tracking Code because the hash codes don't match. This would typically happen on your main domain rather than on a subdomain.

Eduardo Cereto has a post that looks into this issue in more detail and provides another use case where _setAllowHash causes issues. The bottom line here is that you need _setAllowHash to track across domains, but if you're only doing subdomain tracking, it's unnecessary and may cause problems.

2. The leading period causes cookie resets.

Google Code offers the following explanation for using the leading period when using _setDomainName:

"...if you want tracking across lower-level sub-domains:

* dogs.petstore.example.com and
* cats.petstore.example.com,

a leading period is required."

If your site does use lower level subdomains, then you definitely need to use a leading period in order for subdomain tracking to work. If your site does not use lower level subdomain, however, then you're actually better off not using a leading period.

The reason goes back to the hash again. The hash code that the Google Analytics Tracking Code generates when you use the leading period is different than the hash code generated when you don't use the leading period. But the hash code generated when you don't do any subdomain tracking on your main site is actually the same as the hash code generated when you use subdomain tracking without the leading period.

What this means is that if you weren't doing subdomain tracking previously, using the leading period will cause your new Google Analytics Tracking Code to destroy your old cookies because the hash codes don't match. This is similar to what happens when you turn hashing off.

Simply not including the leading period, if you don't have to, means you'll have less cookie reset, which will ease the transition to subdomain tracking.

3. Subdomain tracking without _addIgnoredRef causes self-referrals.

If your site has no subdomains the Google Analytics Tracking Code is able to detect when a visitor's session has expired between pageviews and avoid overwriting their existing referral information with a self-referral or internal-referral from your own site.

That safe guard is removed, however, when you have subdomains, even if your code has the standard subdomain tracking code. This can result in a rather high percentage of self referrals, even though it seems like you've done everything right.

The solution is to use _addIgnoredRef, but how to use it is often misunderstood. The Google Code recommendation is to use something like this:

_gaq.push(['_addIgnoredRef', 'www.sister-site.com']);

I took a very close look at the ga.js code base and observed that something like this won't actually work. The reason is because the Google Analytics Tracking Code considers www.sister-site.com to be the same as sister-site.com, so adding www.sister-site.com as an ignored referral doesn't accomplish much. Using a leading period here also fails. But this works just fine:

_gaq.push(['_addIgnoredRef', 'sister-site.com']);

and in fact, so does this:

_gaq.push(['_addIgnoredRef', 'sister-site']);

The Google Analytics Tracking Code checks each ignored referral string you add and uses the indexOf method to determine whether or not that string is contained within the referring domain. If any of those checks return true, then the referral is ignored. Since the root level domain without the leading period will be contained in any of your subdomains, then passing that to _addIgnoredRef works just fine. This also eliminates the need to add a separate _addIgnoredRef statement for each subdomain.

You may still get self-referrals with _addIgnoredRef, however, though not any more than you would without subdomains. The reason is that _addIgnoredRef only works when the cookies contain existing referral information. If a new visitor comes to your site via a page without Google Analytics Tracking Code, then navigates to a page with Google Analytics Tracking Code, that should result in a self-referral, regardless of whether or not they crossed subdomains.

These types of self-referrals, however, can be avoided by making sure to tag any page of your site. Then, if there are any pages that have this issue, you can dig into your Google Analytics report data and determine exactly which pages are responsible for the issue. And, since you're using _addIgnoredRef, it will be easier to find these pages since you won't have to deal with the noise of self-referrals that occur for no apparent reason.

The important key takeaway here is that _addIgnoredRef should be included standard every time you do subdomain tracking, not just if you notice self-referrals. This will help you avoid needless self-referrals in the first place.

Hopefully this clears up some of the confusion surrounding subdomain tracking with Google Analytics. Feel free to leave any comments or questions.

Google Analytics for Online Advertisers
Here at ROI Revolution, we consider Google Analytics tracking essential for paid search, so it's included in our PPC Campaign Management service.

Comments

Damion said:

Brilliant! I just wish this post was written..... er, the last time I needed to have this as a reference! I had to cobble together a fix from those various inadequate, outdated, fuzzy articles you mention.

I've bookmarked this, and hopefully I'll remember its existence next time the sound of dying tracking is all around. Devs all too often give little thought to how tracking might be affected by their "quirky" subdomain (or even multi-domain) structure, and I'm hoping that this article might be able to solve a few problems before they spiral out of control. Thanks once again!

January 5, 2011 5:13 PM

Eric Polatty said:

If you go to the tracking code section under profile settings in your GA account, and click "one domain with multiple subodmains" under "what are you tracking", I notice the code Google generates for you to use does not include the _setAllowHash tag. But they tell you to include it in the Google Code article for subdomain tracking. I understand it's a free product - but I find Google's inability to make up their minds about how to use their own software frustrating to say the least.

January 6, 2011 9:51 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Eric: My guess is that the Google Code example includes _setAllowHash because it is on a page dedicated to cross-domain tracking. Unfortunately there's currently no Google Code page that just deals with subdomain tracking. I think we lost this during the transition from the traditional ga.js code to the async code, but I'm hopeful that this will be addressed.

The code that's generated from your Google Analytics account is better, but still suffers from the other issues I went over. The lack of an _addIgnoredRef line, or rather the lack of the logic behind the _addIgnoredRef line being executed for an appropriate _setDomainName call, is especially disconcerting since it implies that _setDomainName is sufficient for optimum subdomain tracking.

January 6, 2011 10:37 AM

Eric Polatty said:

@Jeremy - Most of the main Google Code article is on cross-domain situations, but there is a section "tracking across a domain and it's sudomains" and it has the _setAllowHash tag there.

January 7, 2011 10:26 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Eric: It's possible that since it was sandwiched between the other cross-domain examples that the _setAllowHash tag was added unintentionally. Regardless, it shouldn't be there for a subdomain only example.

January 7, 2011 10:32 AM

Mike Sullivan said:

Thank you! Thank you! Thank you!

We added (yet another) subdomain to our environment over the holidays and I tried (yet again) to get rid of the self-referrals. There's so much not-quite-right guidance out there!

Made your suggested changes and today, they have dropped WAY off!

January 7, 2011 11:50 AM

Adam said:

Great article. I'd just about given up on solving the self referrals issue.

Question: if your site uses both subdomains and lower level subdomains, should you use a leading period on both, or just your lower level subdomain pages?

January 7, 2011 12:05 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Adam: If your site has lower level subdomains, then you should use the leading period site-wide.

If you used the leading period on some subdomains and not on others, the hash codes for the cookies would be different, so your cookies would get destroyed every time you crossed from a page using the leading period to a page not using the leading period and vice versa. So regardless of whether you decide/need to use the leading period or not, you want to be consistent.

January 7, 2011 2:09 PM

david said:

Hi Jeremy,

This article of yours was definitely a nice reading.

I experienced myself lots of issues a few weeks ago when adding subdomain tracking to our site, following Google instructions. One of the main problems was a huge boost of direct traffic (we were using leading period, but we didnt use SetAllowHash).

I am willing to try your solution now. However, would you still recommend this implementation (no period and AddIgnoreRef) even for the traditional ga.js code?

January 10, 2011 7:20 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@David: Yes, I would recommend this solution even if you're using the traditional ga.js code. This would look something like the following:

var pageTracker = _gat._getTracker("UA-12345-1");
pageTracker._setDomainName("example-petstore.com");
pageTracker._addIgnoredRef("example-petstore.com");
pageTracker._trackPageview();

A sudden influx of direct traffic can result from going from no subdomain tracking to subdomain tracking with the leading period. Removing the leading period may help, but this depends on how long you've had the code with the leading period up. There aren't any hard or fast rules on this, but I would say that if you've only had the code with the leading period up for a month or more, you might be better off sticking with it at this point.

There's nothing inherently wrong with using the leading period. The main issue I have with it is that for a site that the hash code generated when you use the leading period is different than the one generated when you don't have subdomain tracking at all. If you've already been using the leading period for a significant amount of time, then switching your code to not use the leading period may be just as bad for tracking as switching to using the leading period in the first place.

Also, for a brand new Google Analytics installation, using the leading period is perfectly fine.

January 10, 2011 8:02 AM

David said:

Thanks for your advice, Jeremy. I will keep your considerations in mind and try your proposed subdomain tracking code.

We had the code with the leading period for just a couple of days. The breakage of the data was big enough to get quickly back to the older version, even though it was not taking into account the existing subdomains.

Hopefully I will get a chance to try your suggestions some day next week. Our site has a large amount of traffic, so after a few hours we will be ready to say if it is working or not. I will let you know ;)

January 10, 2011 10:19 AM

Cloga said:

Excellence article!Thank you!

January 10, 2011 10:46 AM

Cristina Chetroi said:

Hi Jeremy!
The _addIgnoredRef tip to minimise self-referrals is great, as they really are a pain. Thanks!

I also remember someone mentioning the inconsistency between the code GA console generates for subdomain tracking (no setAllowHash to false) and the official documentation.

We all wish domain hashing needn't be compromised. But the reality is that it often is - it's common that a client decides to introduce subdomains or other domains at a later stage and you need to tweak the snippet as the result.

So, when it happens, would it be possible to introduce some sort of cookie checkup for returning visitors and do some sort of merge instead of setting a second set cookies/destroying them?

January 12, 2011 5:19 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Cristina: It would certainly be possible to do that. I've done something similar to that before with cookies that were generated with _setNamespace, so it shouldn't be that hard. I have some other ideas about how this might be done as well, something I'm hoping to write about in a future post.

January 13, 2011 7:54 AM

Liz said:

would i use this customization on all subdomains and the top level domains? Or just all the subdomains I want to track - I will have about 4 or 5 of them.

Thanks

January 27, 2011 2:27 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Liz: I would recommend using the modification on all subdomains and top level domains. I have seen some cases where people wanted to track certain subdomains only so they could see traffic coming from other subdomains as referrals, but this is not an ideal setup. Inevitably someone also wants to track the other subdomains, which gives you strange mix of referrals from subdomains and original referral data to those subdomains showing up in your reports. Instead, you should track everything and use filters in Google Analytics to exclude the unwanted domains.

January 27, 2011 4:26 PM

Bernd said:

You wrote:
_gaq.push(['_setDomainName', 'example-petstore.com']);

Google says:
_gaq.push(['_setDomainName', '.example-petstore.com']);

(see the dot before domainname).

What is the difference?

January 30, 2011 2:16 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Bernd: The main differences are that:

1. Each generates a different hash, but not including a leading period has the same hash as no subdomain tracking at all.
2. Including a leading period works for sites with lower level subdomains (ex. buy.store.example-petstore.com).

Google includes the leading period to account for #2. The reason I don't include the leading period is because of #1. It feel that it's more likely that someone is transitioning their code from no subdomain tracking to subdomain tracking than that they have lower level subdomains.

So, as mentioned in the article, if you have lower level subdomains, or if you're setting up Google Analytics Tracking Code on your site for the first time, use the leading period. If you don't have lower level subdomains and you've had Google Analytics Tracking Code on your site for a while, then don't use the leading period.

January 31, 2011 7:54 AM

Bernd said:

OK, thank you very much, Jeremy!

January 31, 2011 1:33 PM

Nick said:

I'm a little confused. Your second point says that you have to use the leading period if you have lower level subdomains, but then at the end you said don't use if you don't have to.

Let's say I have example.com and store.example.com, would I want to use the leading period to track this properly?

January 31, 2011 5:52 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Nick: The only time you have to use the leading period is if you have lower level subdomains. For your example, the leading period is unnecessary for tracking this properly because you don't have any lower level subdomains. You'd have to have another level of subdomain tacked on to there, such as buy.store.example.com.

If you don't have lower level subdomains and you're setting up Google Analytics for the first time on a site, then you have the option to either use or not use the leading period. I tend to not use it as this tends to be more stable, again because the hash code is the same as if you didn't have subdomain tracking on the main domain. So if someone else sets up a Google Website Optimizer test on your homepage, for example, and forgets to add subdomain tracking modifications, this isn't as big of a deal if you had implemented subdomain tracking without the leading period.

The main benefit to using the leading period for new sites without lower level subdomains is that you'll have less people question your setup since it's closer to the Google recommendations.

For sites with existing Google Analytics Tracking Code that you want to update to use subdomain tracking code, not using the leading period will lead to a much smoother transition. Of course, if your site also has lower level subdomain, you'll have to bite the bullet and use the leading period anyway.

Whichever way you decide to go, make sure that you apply that decision consistently across your site. Having some pages that use the leading period and some that don't will wreak havoc on your site.

February 1, 2011 7:56 AM

Chris said:

I'm working on a WordPress MultiSite project which uses subdomain, some of which are mapped to other domains. So what I'm doing really is more in line with the Google example since its not just sub-domain tracking but cross-domain tracking. My question to you is is there any benefit to using _addIgnoredRef for cross-domain tracking? Or could it hurt in any way? I'm looking to reduce self referals as much as possible.

February 4, 2011 12:21 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Chris: Using _addIgnoredRef will still help some with preventing self-referrals. You should have one _addIgnoredRef statement for each root level domain. _addIgnoredRef only ignores a referral if there is previous referral data to fall back on.

So if you have any links between domains that aren't tagged with the proper linking parameters, this will show up in your reports as self-referrals, even if you use _addIgnoredRef. This is a good thing, because it provides visibility for fixable self-referrals.

If there is previous referral data, however, _addIgnoredRef will preserve it. This can be especially useful in situations where you can tag links to a third-party domain, but have trouble tagging links going back to the original domain.

February 4, 2011 8:33 AM

Rob said:

I tried using Google's subdomain tracking suggestion to no avail. For 1 day I did see in GA URL's from the subdomain but I have not been able to figure out how. I came upon this blog after discussing this with a GA expert who has been gracious enough to help us try a few options.

So I adjusted the subdomain code to look like this, per your suggestions:

var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-xxxxxxx-y']);
_gaq.push(['_setDomainName', 'cae-nyc.org']);
_gaq.push(['_addIgnoredRef', 'cae-nyc.org']);
_gaq.push(['_trackPageview']);


The primary/main Drupal-driven domain has this:


var _gaq = _gaq || [];
_gaq.push(["_setAccount", "UA-xxxxxxx-y"]);
_gaq.push(['_setDomainName', 'cae-nyc.org']);
_gaq.push(['_addIgnoredRef', 'cae-nyc.org']);
_gaq.push(["_trackPageview"]);

Now, a thing to note: we have 2 URL's that we use, hosted on a share GoDaddy account: caenyc.org and cae-nyc.org. (Notice a hyphen). The subdomain does NOT have a hyphen it' all advocacy.caenyc.org. I do not have access to an Apache httpd.conf file so I have to use GoDaddy's GUI/Total Domain Control to create the redirect. Could that be causing the problem? Can you peak at both domains & view their source?

Thanks!

Rob

February 8, 2011 9:44 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Rob: Your code should be different depending on which domain it's on. So on cae-nyc.org (with the hyphen), your code should look like the following:

var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-xxxxxxx-y']);
_gaq.push(['_setDomainName', 'cae-nyc.org']);
_gaq.push(['_addIgnoredRef', 'cae-nyc.org']);
_gaq.push(['_trackPageview']);

But on caenyc.org (without the hyphen), your code should look like the following:

var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-xxxxxxx-y']);
_gaq.push(['_setDomainName', 'caenyc.org']);
_gaq.push(['_addIgnoredRef', 'caenyc.org']);
_gaq.push(['_trackPageview']);

The value you pass to _setDomainName must match the domain it's on, otherwise the code will fail. This is also true when you're tracking both example.com and example.net.

I also don't know if visitors can go back and forth between cae-nyc.org and caenyc.org. If they can, then that falls under the realm of cross-domain tracking, which requires a completely different set of tracking code modifications. Still, you'll need to fix the _setDomainName line on caenyc.org to get any kind of tracking there at all.

February 8, 2011 1:03 PM

Rob said:

Sigh, I wish I had tried the obvious yep that worked. And yes people can go from the sub-domain to the main domain and vice verse.

So for example, an email campaign might start with the sub-domain. Then a person fills out the form on the sub-domain, and clicks on Home, which goes back to the main www domain.

Or, people will click on a link from www, e.g., on the home page, and go to the sub-domain, fill out the form, and may hit home. Does that mean cross-domain?

Also, using the sub-domain filter, the Content report is showing the paths with a leading / like this:

/advocacy.caenyc.org/site/apps/kb/cs/contactsearch.asp

or

/advocacy.caenyc.org/site/c.rwL4JlO7KzE/b.6421085/k.DF6F/Petition_to_Incoming_Schools_Chancellor_Cathie_Black/apps/ka/ct/contactus.asp?c=rwL4JlO7KzE&b=6421085&en=ftINKXMILiKPJ5PUJeILI3OLInKZI7OKJgIXK6OQKtK9F


I take it I can transform the URL with another filter?

February 8, 2011 4:53 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Rob: You only need to implement cross-domain tracking if a visitor can move across root level domains. Going from avocacy.caenyc.org to www.caenyc.org does not count as cross-domain because you're just moving from one subdomain of caenyc.org to another.

Going from avocacy.caenyc.org to www.cae-nyc.org, however, does count as cross-domain tracking and requires additional modifications to your code, as well as modifications to the links going between domains. Generally it's something to be avoided if at all possible.

In your situation, the easiest way to avoid the issue is to just 301 redirect visitors who request cae-nyc.org pages to the appropriate caenyc.org page. This eliminates the need for cross-domain tracking and dramatically simplifies your Google Analytics setup.

With regard to filters, yes, you can apply additional filters after the subdomain filter. Those filters will be applied to the modified URL instead of the original URL, so you can use this to change the URL to look exactly how you want it to in Google Analytics. Also, you may want to look at Exclude URL Query Parameters under the Main Website Profile Information to remove any unnecessary query parameters and clean up reporting even further. This is usually easier than using filters to remove the query parameters.

February 9, 2011 7:57 AM

Emily said:

I have multiple domains that I have the same UA# (cookmedical.com, cookbiodesign.com and cookartlab.com). These domains feed traffic between each other and so it would be helpful if I could track them as if they were all the same site to track users between the domains. Based on this information it sounds like I should add the following to all of the pages in all the domains:

_gaq.push(['_setDomainName', 'none']);
_gaq.push(['_addIgnoredRef', 'cookmedical.com']);
_gaq.push(['_addIgnoredRef', 'cookbiodesign.com']);
_gaq.push(['_addIgnoredRef', 'cookartlab.com']);

Am I understanding you correctly?

February 9, 2011 8:48 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Emily: The _addIgnoredRef lines may help with some self-referrals issues, but they're not directly related to cross-domain tracking.

Cross-domain tracking in Google Analytics is the sort of thing that really deserves a series of posts, but I'll try to summarize it as best as I can within this comment.

First, I generally avoid using _gaq.push(['_setDomainName', 'none']); because it does too much. _gaq.push(['_setAllowHash', false]); (no quotes around false) accomplishes the minimum for cross-domain tracking, so it's preferred.

Second, you'll also need to add _gaq.push(['_setAllowLinker', true]); (again, no quotes around true).

Third, you'll need to modify the links between domains. The easiest way to do this is to have the following onclick attribute in the link:

onclick="_gaq.push(['_link', this.href]); return false;"

This covers most scenarios, but not all of them. There will likely be additional nuances that these instructions won't handle. The official Google Code article may help with some of these.

Here are some other things to keep in mind:

1. _link invokes a javascript redirect, which means the referrer won't be available on the receiving page in IE. There are other ways to do this that preserve the referrer, but they are more advanced.
2. _linkByPost may work with forms that use GET instead of POST, but you'll have to specifiy true in the third parameter, that is:

_gaq.push(['_linkByPost', this, true]);

This passes query parameters through the anchor text instead of the query string. This means you'll also need to add _gaq.push(['_setAllowAnchor', true]); to your Google Analytics Tracking Code.
3. It's generally preferred to accomplish linking between domains in a more dynamic way. You might be able to build this into a template driven site, or use a script that modifies onclick attributes of links dynamically.
4. You should try to minimize redirects between domains. These will often do unintended things to query parameters and anchor text and make cross-domain tracking very difficult or impossible.

Because of all the complications involved in cross-domain tracking, you may want to consider purchasing a support plan to ensure that everything is set up correctly.

February 9, 2011 9:18 AM

Emily said:

Thanks that helps a lot. I talked to my developer about this and we're building a dynamic script to add the onClick function to the links that are moving between domains that we want to track together.
I agree that it would be best if we didn't have this highly related content on different domains and we are in the process of redesigning our overall site to include the pages that are currently on separate domains. In the mean time we really need to be able to see how users are moving through our sites.

Thank you for all your help!

February 9, 2011 10:44 AM

Eduardo Cereto said:

The argument that the leading dot can cause problems when you're changing a GA implementation is valid. But what's not clear in the post is your opinion about new implementations.

Since a new implementation doesn't have any already set cookie we should bother, than I think there's no drawback about using the leading dot.

I always use the leading dot in my new implementation, and will keep doing so.

I'm not only worried about the sub-sub-domains. But the leading dot feels more compliant with the RFC that specifies that the absence of it can cause Rejection of the cookie. I'm not sure how many browsers acctually comply to that statements, none I know of. Still I'd rather not take my chances.

http://www.ietf.org/rfc/rfc2109.txt

Quoting the RFC:
4.3.2 Rejecting Cookies
...
* The value for the Domain attribute contains no embedded dots or
does not start with a dot.

[page] 4
Domain=domain
Optional. The Domain attribute specifies the domain for which the
cookie is valid. An explicitly specified domain must always start
with a dot.

February 10, 2011 10:32 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Eduardo: I think that you can argue it either way for new Google Analytics implementations. I prefer not to use the leading period even for leading implementations (assuming of course that there aren't any sub-sub-domains). The reason is that this type of setup tends to be more forgiving when it comes to things such as rogue Google Website Optimizer tests where someone forgot to add subdomain tracking modifications.

If the RFC were an issue, then it seems like Google would have addressed this in the standard Google Analytics Tracking Code. As stands right now, if you don't do any subdomain tracking at all, then the cookies are set without the leading period. So this leads me to believe that it's a non-issue at least as far as cookie compliance is concerned.

Either way you approach this, you're going to have exceptions:

1. If you default to using the leading period, then anytime you add subdomain tracking on a site that already had Google Analytics implemented, then you'll have to consider how much of a negative impact using the leading period is going to have and possibly not use it.
2. If you default to not using the leading period, then anytime you add subdomain tracking you'll have to make sure/hope there aren't any sub-sub-domains.

For me, I find that the exceptions for #2 crop up far less frequently than for #1. Not only that, handling the exceptions for #2 is pretty cut and dry, whereas handling those for #1 involve much more of a judgment call.

Also, to be perfectly honest, I've always felt more comfortable not using the leading period. It's always felt like the right way to do it. It seems to lead to safer setups. But I can easily see how someone could have started out always using the leading period and so instead they feel more comfortable using, it feels right, it seems safer. So I'm OK with someone taking the #1 approach to it instead, but I'll probably continue taking the #2 approach.

February 10, 2011 12:49 PM

Steffen said:

Hey Jeremy, thanks for your post. Very interesting.

I'm facing the following problem: with a few days gap after deploying your recommended tracking setting, traffic from a referring subdomain drops significantly. Expected effect on _addIgnoredRef(). Meanwhile, direct traffic increases. That - in turn - is not what I expected and in my case not supposed to be. What's the benefit from tracking subdomain traffic as direct traffic? That's even more confusing than tracking as referring. I expected that traffic to become "internal" traffic. How to achieve that?
And why is that gap from ... say 10 days?

Thanks in advance.

February 24, 2011 7:56 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Steffen: I can't determine the exact cause without seeing the code or looking at the site, but if traffic from a subdomain is showing up as direct, then that indicates some type of code inconsistency between the main domain and the subdomain. Here are some things to consider:

1. Are you wanting to track the main domain and the subdomain together? Sometimes people want to track these separately, or they don't want to/can't track the subdomain for some reason and want it tracked as a referring source. This article assumes that you do want to track them together.

2. If you're tracking the main domain and the subdomain together, then the Google Analytics Tracking Code on each should be very similar, if not identical. In particular, the _setDomainName and _setAllowHash statements (or lack thereof) must be identical. You can't have a leading period on one and not on the other, use _setDomainName("none") on one and not on the other, or use _setAllowHash("false") on one and not on the other.

3. Are you running any Google Website Optimizer tests on either the main domain or the subdomain? Similar to #2, the Google Website Optimizer code must have the same set of modifications as your Google Analytics Tracking Code. This is fairly straightforward for the tracking script and conversion script, but the control script needs to be modified using equivalent urchin.js style modifications.

4. Is there any other Google Analytics Tracking Code on any of the pages? This includes legacy code, code put there by someone else for some other purpose, or even UTM code for Urchin. Any extra code like this will need to either be modified to match your Google Analytics Tracking Code or removed.

February 24, 2011 8:20 AM

Cory said:

Hi Jeremy,

This is such a great article. I recently spent a lot of time scratching my head over some self-referrals until we saw this.

I quickly implemented your code as outlined above on a simple (/path/page.aspx) www domain and a developer added matching script on a more complex transaction subdomain(pages.aspx?pid=000 etc)

Unfortunately, I'm able to see only traffic that moves from the "complex" (www) site to the "simple" (subdomain) site but not the other way around.

What do you think that means? On which CMS should I look to edit?

Thank you!

February 24, 2011 1:08 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Cory: My previous comment most likely applies here as well. In particular, you should check both sites for legacy Google Analytics Tracking Code that might have a different set of modifications than the code you just added. The legacy code will then have to either be modified or removed.

February 24, 2011 1:20 PM

Peter O'Neill said:

Hi Jeremy,

Just had a long discussion with an ex-colleague about _addignoredref and want to clarify what the impact of it is.

In point 3 of the blog, you recommend using it to avoid self-referrals when a visit session expires between pageviews. That makes sense but I can't see this causing a high percentage of self-referrals. For most sites, this should occur a minimal number of times. If a site has many visits timing out (maybe due to video), would suggest increasing length of visit.

Instead won't using this code eliminate recording of all self referrals as they will all be reported as the previous referrers or as Direct? As you say in one of the comments, this information can be useful for finding untagged pages or untagged links between subdomains.

Thanks - Peter

March 4, 2011 6:25 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Peter: Pages with a lot of content or videos can certainly exacerbate the issue, but self-referrals will often make up 1 to 2 % or more of traffic even on sites without videos or long sales letters.

I'll speculate on why and say that in general, we often don't have a captive audience on the web. Someone may be on one site, think of something and open up a tab to check something on another site, or maybe they notice they have an email, or maybe they get a phone call, etc. Depending on the type site, they may also be doing comparison shopping and have 10 different tabs open at once.

Regardless of why this is happening, _addIgnoredRef is a nice solution because it only applies to visitors that have previous referral data available. This means that a visitor won't just show up as direct instead of a self-referral, unless of course they were previously direct.

A new visitor who starts at an untagged page and moves to a tagged page will still show up a a self-referral, even if you're using _addIgnoredRef. Eventually this will happen for enough visitors that you'll see the problem in your Google Analytics reports.

This is especially true of untagged landing pages, but a page not designed to be a landing page will usually still end up as a landing page for enough people to point out the problem in Google Analytics. But if you still have the 1 to 2% of noise coming from self-referrals that could have easily been prevented by _addIgnoredRef, it makes it much harder to catch these pages.

Even if self-referrals only showed up for true problems, I'd still use _addIgnoredRef because it's more important to preserve referral information when possible than to fix a problem on a single page. If the page is important enough, then the tagging issue on that page will become obvious at some point anyway, even without a bunch of self-referrals to point it out. If it's not a very important page, then the misfortune of having that page missing from your reports is still outweighed by the benefit of having correct referral information for those visitors who spent a little too long on that page (or the previous page) for whatever reason.

March 4, 2011 7:57 AM

Peter O'Neill said:

Thanks for the detailed reply. I hadn't realised the degree to which self-referrals are driven by visitors timing out - that does change the situation.

I also agree with your logic on using _addIgnoredRef based on how you have described it as working. However that appears to be different to the Google description (which I know is wrong occasionally). They say

Excludes a source as a referring site. Use this option when you want to set certain referring links as direct traffic, rather than as referring sites. For example, your company might own another domain that you want to track as direct traffic so that it does not show up on the "Referring Sites" reports.

This suggests that all traffic from the domain specified will be reported as Direct. As opposed to what you have written which is it will pick up the previous referrer for returning visitors and have no affect on new visitors. Have you found that this is the way it works in practice and that this is another example of where Google needs to update their documentation?

March 4, 2011 12:49 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Peter: Yes, I would say that the Google documentation on _addIgnoredRef is a bit misleading. In practice, it works as I've described it.

March 4, 2011 1:07 PM

Peter O'Neill said:

Ok, that explains my confusion. Thanks for the assistance and the detailed explanations given.

March 4, 2011 1:26 PM

Rene said:

Very useful information and i did understand it until you mentioned crossdomain tracking needing a different approach with:
_gaq.push(['_setAllowHash', false]);
_gaq.push(['_setAllowLinker', true]);

What if you want to track example.com, store.example.com and example2.com together.So this would be Tracking Across Multiple Domains and one Sub-domain.

Would you use the following?

example.com
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-12345-1']);
_gaq.push(['_setDomainName', 'example.com']);
_gaq.push(['_setAllowHash', false]);
_gaq.push(['_setAllowLinker', true]);
_gaq.push(['_addIgnoredRef', 'example.com']);
_gaq.push(['_addIgnoredRef', 'example2.com']);
_gaq.push(['_trackPageview']);

store.example.com
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-12345-1']);
_gaq.push(['_setDomainName', 'example.com']);
_gaq.push(['_setAllowHash', false]);
_gaq.push(['_setAllowLinker', true]);
_gaq.push(['_addIgnoredRef', 'example.com']);
_gaq.push(['_addIgnoredRef', 'example2.com']);
_gaq.push(['_trackPageview']);

example2.com
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-12345-1']);
_gaq.push(['_setDomainName', 'example.com']);
_gaq.push(['_setAllowHash', false]);
_gaq.push(['_setAllowLinker', true]);
_gaq.push(['_addIgnoredRef', 'example.com']);
_gaq.push(['_addIgnoredRef', 'example2.com']);
_gaq.push(['_trackPageview']);

March 15, 2011 5:31 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Rene: The code for example2.com should be a little different:

var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-12345-1']);
_gaq.push(['_setDomainName', 'example2.com']);
_gaq.push(['_setAllowHash', false]);
_gaq.push(['_setAllowLinker', true]);
_gaq.push(['_addIgnoredRef', 'example.com']);
_gaq.push(['_addIgnoredRef', 'example2.com']);
_gaq.push(['_trackPageview']);

It'd important that the _setDomainName call match the root level domain of the site the code is on. If it doesn't match, then no cookies will be set and you won't get any Google Analytics data for those pages.

March 15, 2011 7:51 AM

Jeff said:

What if I want to track all of my subdomains independently? How do I set that up?
Each of my clients will have a branded website for themselves that I am hosting as a subdomain. I need to be able to generate a report showing Client A his traffic without any other clients info in there.
Currently we only have about 8-10 of these clients but the number is growing and could reach into the hundreds.
Any suggestions for this GA challenged guy?
Thanks in advance!
Jeff

March 28, 2011 4:19 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Jeff: See the comment at the end of the this post.

March 28, 2011 5:03 PM

Jeff said:

Thank you! I didn't realize there was a different post and kept looking at this one for a reply.
Thank you again!

March 30, 2011 12:59 AM

anobre said:

Hi there!
I've implemented this tracking code style and it seems to be working great with a catch. Now when i go , for instance, to top content report and click 'visit link' i'am always sent to the top domain when in most cases i should be redirected to a subdomain.

Cheers,

April 14, 2011 3:11 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@anobre: You'll need to add two steps to this:

1. Add a filter to add the hostname to the beginning of the request uri. Usually I use something like this:

Filter type: Custom Filter (Advanced)
Field A: Hostname
Extract A: (.*)
Field B: Request URI
Extract B: (.*)
Output to: Request URI
Constructor: $A1$B1
Field A Required: Yes
Field B Required: Yes
Override Output Field: Yes

2. Edit the Main Website Profile Information and change the Website URL to:

http://

This won't fix the existing data in your profile, but going forward, clicking on a link will go to the correct subdomain. This works for sites with multiple domains as well.

April 14, 2011 3:44 PM

Ryan said:

Hi Jeremy - great post. I was trying to follow along your comment discussion with Rene about cross-domain with sub-domain tracking but believe I missed something.

If I am tracking from www.mainstore.com (or mainstore.com) to 3rd party checkout which is a sub subdomain: checkout.sub.main.net - is what I have correct:


Site (mainstore.com):
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-XXXXX']);
_gaq.push(['_setDomainName', '.mainstore.com']);
_gaq.push(['_setAllowHash', false]);
_gaq.push(['_setAllowLinker', true]);
_gaq.push(['_setAllowAnchor', true]);
_gaq.push(['_addIgnoredRef', 'mainstore.com']);
_gaq.push(['_trackPageview']);


3rd Party (checkout.sub.main.net):

var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-XXXXX']);
_gaq.push(['_setDomainName', '.main.net']);
_gaq.push(['_setAllowHash', false]);
_gaq.push(['_setAllowLinker', true]);
_gaq.push(['_setAllowAnchor', true]);
_gaq.push(['_addIgnoredRef', 'mainstore.com']);
_gaq.push(['_addIgnoredRef', 'main.net']);
_gaq.push(['_trackPageview']);


Does that look correct (assuming the linker tags are in place)?

April 14, 2011 4:30 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Ryan: That code looks fine. The one thing I would add is that the _setDomainName call is optional for the third party domain unless you're tracking across subdomains on the third party domain. That is, if a visitor goes from your site to checkout.sub.main.net and doesn't see any other subdomains on main.net, then there's no need to do subdomain tracking for the third party domain.

Also, if you have two sites, one with sub subdomains and the other without sub subdomains, technically you only have to use the leading period on the site with sub sub domains. So even if a visitor could go from checkout.sub.main.next to somewhere else on main.net, that doesn't mean you need a leading period for mainstore.com as well.

As discussed in the article, you can certainly still include the leading period if you feel strongly about it, but there are benefits to not using the leading period which you might be able to take advantage of. It might also be difficult to remember which sites you have to use it for and which you don't, in which case always using the leading period may make more sense.

April 14, 2011 4:52 PM

Ryan said:

Great, I will try taking out the leading periods. Thank you Jeremy

April 14, 2011 4:55 PM

Brian Moore ? said:

Some thing tells me I ruined/fubar'd my analytics.

ok I have a ecommerce site using a 3rd party shopping cart.

my analytics code is this:
mysite.com

var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-*********-1']);
_gaq.push(['_setDomainName', 'none']);
_gaq.push(['_setAllowLinker', true]);
_gaq.push(['_setAllowHash', false]);

3rd party cart
cart.com

var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-********-1']);
_gaq.push(['_setDomainName', 'none']);
_gaq.push(['_setAllowLinker', true]);
_gaq.push(['_trackPageview', 'insert_page_name']);


ever since i implemented this code change so my boss could get the google adwords conversion tracking working the main site shows up as a referrer and now the ecommerce conversion rate in google analytics has droped to zero.

help please.

April 19, 2011 1:35 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Brian: I don't see a _trackPageview call for the mysite.com analytics call, but you may have just left that off. It's also not necessary to have both _gaq.push(['_setDomainName', 'none']); and _gaq.push(['_setAllowHash', false]); on the mysite.com code. You should probably drop the _setDomainName call.

My best guess is that you probably had some sort of linking in place that is now broken as a result of updating your code to the async version. Without knowing anything else, the easiest way you can probably fix that is to add the following after your Google Analytics Tracking Code:

_gaq.push(function() {
window.pageTracker = _gat._getTrackerByName();
});

You can add this after both your mysite.com code and your 3rd party code, assuming that the 3rd party domain links back to your main domain correctly.

April 19, 2011 2:45 PM

Ryan said:

Hi Jeremy,

Unfortunately I am still getting mostly (direct) transactions in my reporting. About 1/3 do contain the referring keyword so I believe I must be on the right track but am perhaps missing something.

This is with a Yahoo! store and I believe I have to the two links tagged correctly that point to the cross-domain from sunshineyoga.com to checkout:(yahoo.net).

Can I pay you to review at my implementation (via view source) to make sure I have the cross links tagged?

When I run through in WASP it looks like the cookie retains all the data so I'm not quite sure what the issue is.

Thank you!

April 20, 2011 11:01 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Ryan: We no longer offer stand-alone Google Analytics support plans. You should look into using Monitus in order to track Yahoo Store. That is what we always recommend for tracking Yahoo Store.

April 20, 2011 12:20 PM

Ryan said:

Do you have anyone you can refer me to?

Not really interested in having to pay monthly for GA data.

Thanks!

April 20, 2011 2:37 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Ryan: Monitus is the only viable solution for tracking Yahoo Stores. So if you don't want to pay monthly, you'll probably want to look into using something besides the Yahoo Store.

April 20, 2011 3:01 PM

Dan said:

If my sub domains have no reference or relationship to the TLD, would I not get valid results if I treated the sub domain the same as a TLD?
I setup a site in a WP multi site environment so wouldn't I just treat the sub domain the same as a TLD, generate and implement analytics the same way I would for a TLD?
Dan

May 2, 2011 10:34 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Dan: If the subdomain does not refer to the main domain and vice versa, then you do not need to implement subdomain tracking. The standard Google Analytics Tracking Code will work fine for both sites. You can either use separate account numbers (within the same Google Analytics account) to track each domain separately, or use the same one if you want roll-up reporting.

The same goes for multiple domains as well. If you have multiple domains and no domain links to any of the other domains, then there's no need to implement cross-domain tracking. The standard Google Analytics Tracking Code will work fine for all sites. And again, you can track the sites separately or in a roll-up profile (or both).

May 4, 2011 8:03 AM

Eric W said:

Hi Jeremy - great article. I recently added similar code in an attempt to fix self-referrals for our websites. The result was partially successful, they dropped dramatically for April (implemented 3/31).

However, we also experienced a massive unexplained drop in Visits and UV's, while our PV and every other performance metric increased.

Is there any reason that getting rid of self-referrals would lower UV's (or, to phrase properly, improperly having self referrals would have been inflating UV counts?)

Thanks,
Eric

May 9, 2011 9:20 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Eric: Self referrals will usually result in inflated visit counts. Inflated UV counts are less common, but this is also possible depending on what your code looked like before. Unique visitor counts are largely based on the __utma cookie remaining intact. So if your Google Analytics Tracking Code setup results in this cookie being recreated, then you will get an artificial spike in UVs.

May 10, 2011 7:59 AM

Eric W said:

Thank you very much! I was able remove my fix and test it and actually see the Unique Visitor ID change, creating extra UV's. Appreciate your feedback!

May 10, 2011 11:06 AM

Eric said:

Another question for you Jeremy.

Our sites have 1 main domain and 1 main subdomain. We get a ton of self referrals and corrected some of them by adding 1 missing line of code to our main domain pages.

However, we are still getting quite a few.

Here is the code we are using. Is this correct?


var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA of Main Page']);
_gaq.push(['_setDomainName', '.ericsite.com']); (this line was missing and was added 5 weeks ago, fixing about 60% of our self referrals)
_gaq.push(['_trackPageview']);

_gaq.push(['_setAccount', 'UA of rollup account']);
_gaq.push(['_setDomainName', '.ericsite.com']);
_gaq.push(['_trackPageview']);
_gaq.push(['_setAccount', 'UA of another rollup account']);
_gaq.push(['_setDomainName', '.ericsite.com']);
_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);
})();

May 12, 2011 4:30 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Eric: As mentioned in the post you should also add the following line for each account:

_gaq.push(['_addIgnoredRef', 'ericsite.com']);

This line can go right after the _setDomainName line for each account. Also note that I intentionally left out the period in front of ericsite.com. This is correct regardless of whether you use a leading period with _setDomainName or not.

May 12, 2011 4:45 PM

Eric said:

Thanks again, will report back results!

May 12, 2011 9:14 PM

Eric said:

Greetings again -

The addition of that code has had no impact. If we had our sites live for a solid 6 months with a subdomain issue, is it possible/likely that the remaining self-referrals we still see after fixing things are simply "baked" in to cookies and not fixable until the cookie expires?

Very much at a loss now.

Thanks again!
Eric

May 23, 2011 7:46 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Eric: Yes, it may take some time to work itself out. Not only do you have return visitors who already have cookies for self-referrals, but you also potentially have return visitors who are viewing cached pages with the old code that may still have their referral information overwritten with a self-referral.

Also note that this code change doesn't address other fixable sources of self-referral traffic. For example, if you have a landing page that's missing the tracking code altogether, the code change won't fix those self-referrals, but you can still fix the issue by adding the tracking code to that landing page.

May 24, 2011 7:13 AM

Eric said:

Couple more things.

#1 - I've had one site that has been fixed for 3 months now (2/22 fix date). That being the case, I'd expect their remaining self-referrals to be slowly dropping off over time. However, they are staying pretty flat since the initial drop from my 2/22 fix. That concerns me.

#2 - I added the hash setting to the site I tried your suggestion on last week. It now looks like this :
var _gaq = _gaq || [];
_gaq.push(['_setAccount', '']);
_gaq.push(['_setDomainName', '.ericsite.com']);
_gaq.push(['_addIgnoredRef', 'ericsite.com']);
_gaq.push(['_setAllowHash', false]);
_gaq.push(['_trackPageview']);


While the addition of addIgnoredRef last week had no impact on the self-referral count, the addition of setAllowHash false seems to have had a definite impact in lessening the self-referrals.

Does that make any sense to you?

Are there any drawbacks to turning off the hash like that?

Thanks again!
Eric

May 25, 2011 2:02 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Eric: Turning the hash off would cause a cookie reset for all your return visitors. So while this does remove all of the lingering self-referrals, it also removes all of the referral attribution for all of your return visitors. Most likely you're now seeing a jump in direct traffic.

May 26, 2011 7:37 AM

Eric said:

Yep - that's exactly what happening. Direct jumped from 32% to 49%.

Is the cookie reset from turning off hash a 1 time thing?

In other words, if I leave it as is, are the cookies being constantly reset for the same user over and over?

Thank you sooo much for the assistance. Invaluable.

May 26, 2011 1:48 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Eric: The cookies will only be reset a maximum of once per user, and only for users visited the site prior to the code change. For new visitors, the cookies will be set correctly for the first visit and will not be reset for subsequent visits (though of course standard attribution rules apply).

May 26, 2011 3:16 PM

Jonathan said:

Hi Jeremy - fantastic post, I've been looking for a way to fix our self-referral issue for a very long time.

Before I implement the changes you suggest (i.e. add addIgnoredRef) , a quick question about leading periods:

We've been using Google Analytics across multiple subdomains (but no lower level domains) for over a year, and have always used setDomainName with a leading period. I know you generally recommend not to use the leading period when making the "switch" to subdomain tracking, but what would you do in our situation, given that we've already used the leading period in setDomainName for such a long time?

Thanks for your help!
Jonathan

June 1, 2011 12:58 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Jonathan: If you've been using the leading period the whole time, then you're probably better off sticking with it. The main exception would if you've often had cookie corruption due to things like poor Google Website Optimizer implementations. In that case, moving to not using the leading period would still cause an initial cookie reset, but might prevent additional cookie resets down the road.

June 1, 2011 5:31 PM

Doug Gebhardt said:

What an amazing post. Thanks so much Jeremy. Looks like it has kept you hopping! I'm wondering about what happens when www2 is showing up in my referral traffic as the number 1 referrer. Would this help to eliminate this sort of self referral? Here is what we have right now.
var pageTracker = _gat._getTracker("UA-1234567-1");
pageTracker._setDomainName(".sample.ca");
pageTracker._setAllowLinker(true);
pageTracker._setAllowHash(false);
pageTracker._trackPageview();
Based on your other answers here, the leading period should be removed in the setDomainName as well to prevent the subdomains as showing up as referrers.
Cheers!

June 5, 2011 9:44 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Doug: The main reason for leaving off the leading period is that it creates cookies that are compatible with the standard, unmodified Google Analytics Tracking Code on your main domain. If you're using the leading period and already have for a while, then switching will cause a cookie reset. Also, whether or not you use the leading period does not affect whether or not you have self-referrals.

Adding the following line should help with some of the self-referrals:

pageTracker._addIgnoredRef("sample.ca");

As mentioned in the post, the leading period should not be used for this method, regardless of whether or not you use it in your _setDomainName call. This call can go right after _setDomainName call.

It's always possible that there may be some other reason why you're getting self-referrals, but this addresses one source of self-referrals caused by subdomain tracking in general.

June 6, 2011 7:26 AM

Devendra Singh said:

Quite informative post, especially because it even tries to correct some documentation mistakes of GA.

A small query please:
We have couple of websites on subdomains. Each one does its own SEO to attract Search Engine Traffic. The Visitors may land to any of the subdomain websites from Search Engine Referral. Later if the Visitor clicks a link to move to the sister subdomain, we still see the original source as the Referral Site. That's okay. But, is there a way to track that how many referrals were transferred to each other (without event tracking)?

Thanks,

DS

July 3, 2011 12:19 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Devendra: You could probably do this to some extent with custom variables or internal site search tracking. Another option would be to use a second tracking object. This would look something like this:

_gaq.push(['_setAccount', 'UA-XXXXXXX-1']);
_gaq.push(['_setDomainName', 'mydomain.com']);
_gaq.push(['_trackPageview']);

_gaq.push(['t2._setAccount', 'UA-XXXXXXX-2']);
_gaq.push(['t2._setDomainName', document.domain]);
_gaq.push(['t2._trackPageview']);

The idea here is that the first tracking object will have its cookies set to the root level domain, while the second tracking object will have its cookies set to the entire domain, including the subdomain. Some key things to notice:

1. Two separate accounts are used (UA-XXXXXXX-1 and UA-XXXXXXX-2).
2. 'mydomain.com' is a string while document.domain is not
3. This will only work reliably well in single domain with subdomain situations.
4. For the same reason as #3, do not use _gaq.push(['_setAllowHash', false]); even if you see documentation that says that you need to for subdomains.

July 5, 2011 7:45 AM

Ruby said:

Hi Jeremy, thanks for writing the article. It is very useful. I am new to GA. I have few questions about subdomain tracking.

I have a website site with sub.example.com and subsub.sub.example.com. The subsub.sub.example.com is not a brand new site so I should use

_gaq.push(['_setDomainName', '.example.com']);

to allow leading time for the site. With the dot in front of the domain name. Is it correct?

The code below should be in both sub.example.com and subsub.sub.example.com sites:

var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-12345-1']);
_gaq.push(['_setDomainName', '.example.com']);
_gaq.push(['_addIgnoredRef', 'example.com']);
_gaq.push(['_trackPageview']);

Also there is another subdomains under the same domain name, for example abc.example.com and efg.example .com. Will the code above track traffic from the other sub domains as well?

Many thanks

July 13, 2011 9:40 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Ruby: Your code looks correct. Because you have multiple levels of subdomains (e.g. subsub.sub.example.com), the leading period is strictly necessary. The same code works for just one level of subdomains (e.g. abc.example.com). The addIgnoredRef call is also correct; no leading period gives you the best coverage since this is simply a substring match using indexOf.

July 14, 2011 10:52 AM

webzdev said:

Hello Jeremy thnak you very much for your post. It was like hell for me to clarify to myself what is right and what is wrong.

I have following situation:
A year ago I did set up GA on a domain example.com BUT code looks like this:
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-xxxxxx-y']);
_gaq.push(['_setDomainName', '.example.com']);
_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);
})();

now I created a subdomain sub.example.com created a separate Profile in GA dashboard. Now I have 2 profiles for site url example.com. I copied GA code suggested by google, pasted it on sub.** but code looks like tihs:
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-xxxxxx-y']);
_gaq.push(['_setDomainName', '.example.com']);
_gaq.push(['_trackPageview']);
(it is the same as this on my main domain) I notice in dashboard there are different profile IDs but they are not addressed in the GA code.

I am confused what exactly should I do to track my subdomain AS A FULLY INDEPENDENT site.
Should I add sub.example.com as new site so I receive a different code or should I retain the second profile with some adjustments??

July 24, 2011 12:25 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

When you add a new profile, you should select the option to add the profile for a new domain rather than an existing domain. This will give you an account number that's separate from your existing profile. Note, however, that the only difference between the two account numbers will be the "-y" at the very end of the number. This is sufficient to track the sites separately.

Also, since you're tracking this subdomain separately, you may want to consider removing the _setDomainName line, to avoid sharing cookies between this subdomain and your existing site.

July 25, 2011 9:16 AM

Vikas Sahdev ? said:

Hi Jeremy,
You are the recognized GA expert here, so I would ask your advice. In between reading multiple threads, I am sort of confused and want to clarify whether what I am doing is correct.

I have two sites: www.example.com and a subdomain www.blog.example.com

What I want is:

1. Sub domain tracking

2. One GA Profile which tracks both the main domain and sub domain.

3. Conversion funnel from all pages on the www.blog.example.com to www.example.com

This is what I have done so far:


1.
I added the below code to www.example.com and www.blog.example.com:

var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-XXXXXX-1']);
_gaq.push(['_setDomainName', 'example.com']);
_gaq.push(['_addIgnoredRef', 'example.com']);
_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);
})();

2.

Created one Master Profile in GA( for www.example.com) without any filters


3.

Created a duplicate of the Master Profile in GA( for www.example.com) with the subdomain filter described earlier in the thread.


Below are the Questions I have:

1. Does the above set up look correct considering what I want to achieve?
2. It has been a day since I set up the second profile but still don't see any visits. Any ideas if something is wrong?
3. I want to implement a funnel whereby i want to track how many visitors from anywhere on www.blog.example.com came to www.example.com. Both the sites don't have default pages in the url( i.e no www.blog.example.com/default.aspx e.g). So in the funnel, how do i define step1 and step 2 urls since both sites have "/" as their default page?

4. Since both the profiles I have contain data from both sites, how do I "filter" reports for one site vs the other? For e.g I woudl like to know the unique visitors to only the blog site and not the main domain site. Is that possible?


Thanks a ton for your help looking into this.


July 29, 2011 5:32 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

Your best bet is to probably use an advanced filter for visits that include both hostnames. You could set this up as a goal, but it would only be useful if you checked the required step box, and even then only within the Funnel Visualization report. When you have a filter that modifies the request uri, the Goal URL and Funnel Steps should match the modified request uri instead, which means that you can do a head match on blog.example.com and www.example.com. The main thing to check if there's still no data is that the other profile is a duplicate of the other one, that is, the web properties should be the same. It's easy to create another profile that uses a -2 instead of a -1 in its Google Analytics Tracking Code.

August 1, 2011 5:29 PM

Vikas Sahdev ? said:

Thanks Jeremy. I have two more questions from your original article:

1. _gaq.push(['_addIgnoredRef', 'example.com']);

If I put the above line in the GA code, both for root domain and subdomain, would I still see the traffic coming from www.blog.example.com to www.example.com. Since I would like to track conversion from the blog site(sub domain) to main site( root domain), I don't want to loose the referrals from blog site to main site.

What reports exactly get impacted by using the code line above? Is it only the Reffering sites report?


2. _gaq.push(['_setDomainName', 'example.com']);

We had a separate GA ID for the subdomain and root domain and thus separate profiles in GA for each of those and we were using leading period in the setDomainName. This was happening for over a year.

Recently we started using the same GA ID for the subdomain and root domain and one profile for both sites with the cross domain filter applied.

In this situation, do you recommend that we keep the leading period or remove it in the above line of code ?

I am also confused by your original comment in the article which says "What this means is that if you weren't doing subdomain tracking previously".

I am not sure what exactly constitutes "doing subdomain tracking" to be able to say whether that condition applies to us. What I am doing is summarized in the previous post. Does that constitute what you meant by "doing subdomain tracking"?


Thanks again!!

August 9, 2011 7:01 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Vikas: _addIgnoredRef is a soft ignore, that is, it only ignores the referrer if there is pre-existing referral information. For example, if your tracking code is set up so that someone starting on the blog and moving to the main domain is counted as a blog referral, then adding _addIgnoredRef won't change that. If instead someone starts on the main site, moves to the blog, then moves back to the main site, then they will not count as a blog referral, even if they spent more than 30 minutes on the blog, because there were already cookies on the main site.

If you were previously using the leading period with _setDomainName, it's probably best to continue using the leading period unless you've been having problems. For example, if someone keeps setting up GWO tests and they can't remember to add proper subdomain tracking modifications, dropping the leading period might help alleviate some of those issues.

"Doing subdomain tracking" refers to using _setDomainName to share cookies across subdomains, regardless of whether you used the leading period. If you have subdomains, but you're not using _setDomainName, then you're not doing subdomain tracking because each subdomain is more or less being treated as a separate site.

In your scenario, it sounds like you want to be able to see traffic that's referred from the blog. In that case, using any form of _setDomainName doesn't make sense because you don't want the cookies to be shared between the two subdomains. _addIgnoredRef probably isn't a bad idea though since it will only give the blog credit when they came to the blog first. You won't easily be able to tell which keywords that sent visitors to the blog resulted in conversions on the main site, however, since those conversions will be credited to the blog instead of the keyword.

August 10, 2011 7:34 AM

Darius said:

Hi,

I tried this but it doesn't work. It still double counts visits over sub-domains, but now it just comes through as all direct. (I implemented it on a website which gets no traffic - so it was a controlled test).

The implementation suggested on the GA website also doesn't work. It ends up with loads of self-referrals.

August 11, 2011 5:47 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Darius: It's hard to know what the issue is without seeing the site. Normally with something like this I would use a cookie viewer like firebug with firecookie and a headers viewer like httpfox so I can see exactly when the issue occurs. Usually you can just use some fake tags like http://www.example.com/?utm_source=test&utm_medium=test&utm_campaign=test and then see when the cookies change to direct.

It may be that there's some rogue code on the page that doesn't have proper subdomain modifications that's causing the issue. This code could be legacy code that's still on the page, Google Website Optimizer code, or possible urchin Urchin UTM code.

August 11, 2011 7:53 AM

Tauseef said:

Hi Jeremy,

Thanks for the information. I update the code to track sub domain and domain traffic. I have two top level domain mobile.customizedstickers.com
blog.customizedstickers.com

The one I am more want to see not as a referral traffic is mobile cause I get conversion from that (Paid and Organic). After changing the code Now getting traffic as a direct.

Any idea why it's doing it or just a old cookies kicking in.

Any help will be highly appreciable.

Thanks in advance.

Tauseef

August 11, 2011 5:16 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Tauseef: Most likely the direct traffic is return traffic to the site. Because both of your domains are subdomains, the cookies by default would have been at the subdomain level. Now that you've implemented subdomain tracking, cookies will be read and created at the root level domain. This means that you may lose information for returning visitors. Over time, this number should decrease and the percentage of direct traffic should go down.

August 12, 2011 9:43 AM

Owen Smith said:

Hi Jeremy,

Perhaps you can help me out with an issue I'm having.

I have a website like so: mysubdomain.x.x.ca

I store static content (css, js, etc) at: static.mysubdomain.x.x.ca

Now, I don't want cookies to get set on the static subdomain for caching purposes.

On my pages, my tracker looks like :
var _gaq=[
['_setAccount',''],
['_setDomainName', 'mysubdomain.x.x.ca'],
['_trackPageview']
];

However the cookies are still set as ".mysubdomain.x.x.ca"

Can you provide any insight on not including lower-level subdomains?

August 14, 2011 2:54 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Owen: If you explicitly need cookies to not be available for any other domains, then you'll need to use something like this:

_gaq=[
['_setAccount',''],
['_setDomainName', 'none'],
['_trackPageview']
];

Then the cookies will only be available to the domain they were set on. Note that this will also affect the hash, so you need to be careful to check that this works as you expect it to. Also, it might be best not to explicitly set _gaq to an array. _gaq is only temporarily an array; it's later rewritten as an object. So it might not always work as expected.

August 15, 2011 8:05 AM

Ken Holden said:

Would this work for issues regarding a secure subdomain? The site is www.planetdj.com. The user is sent to secure.planetdj.com upon beginning check out. (Feel free to see for yourself).
This is the current code we have implemented.


var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-605157-1']);
_gaq.push(['_setDomainName', 'none']);
_gaq.push(['_setAllowLinker', true]);
_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);
})();

All of our conversions are listed as (direct) / (none).

It's not a referral issue, which is why I ask.

Your help would be awesome. Thanks! Great article!!

August 24, 2011 5:02 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Ken: I would recommend something along these lines:

var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-605157-1']);
_gaq.push(['_setDomainName', 'planetdj.com']);
_gaq.push(['_addIgnoredRef', 'planetdj.com']);
_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);
})();

These modifications will track visitors as they move across subdomains of planetdj.com. As long as everything is on planetdj.com, there's no reason to implement cross domain tracking modifications (_setDomainName('none') or _setAllowHash(false), _setAllowLinker(true), etc.).

August 25, 2011 7:28 AM

Ken Holden said:

Yeah that still didn't work. Would there be interference with the cookies? All our conversion traffic is still labeled as (Direct)/(none).

Care to take a peek? Feel free to start the checkout process, as I feel that's where the issue starts.

August 25, 2011 5:28 PM

HopeThisHelps said:

Note that _setAllowHash() has now been deprecated:

http://code.google.com/apis/analytics/docs/gaJS/gaJSApiDomainDirectory.html#_gat.GA_Tracker_._setAllowHash

and the recommendations on the Google site are now a lot closer to the above. I think they are listening ;-)

September 9, 2011 4:14 AM

David said:

Here is the situation our websites share a main navigation / design thus you can easily navigate between 'www.a.com', 'www.b.com' and 'www.c.com' we also have two subdomains of 'www.a.com' that each website uses for quotes & sales those subdomains are: 'secure.a.com' and 'sale.a.com'.

So if you are on 'www.a.com' and click a main navigation item you could go to 'www.b.com' once there say you add an item to your shopping cart you are take to 'secure.a.com'

Here is the solution we have implemented:

On each domain / subdomain we have placed this code:

_setDomainName is the only thing that changes and reflects the domain or subdomain you are on i.e. in this case ".a.com" on the other domains / subdomains it reads ".b.com", ".c.com", ".secure.a.com" and ".sale.a.com".

var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-XXXXX-1']);
_gaq.push(['_setDomainName', '.a.com']);
_gaq.push(['_setAllowLinker',true]);
_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);
})();

$('a').click(function() {
var url = $(this).attr("href");
if (url)
{
if (url.substring(0, 4) == 'http' && url != '' && url != '#' && url.toLowerCase().indexOf('youtube') {
if (url.substring(0, 4) == 'http')
{
_gaq.push(['_link',url]);
location.href = url;
}
return false;
}
}
});

Here are the questions:

We have noticed a large bump in average time on site, why, and how do we correct this?
Have we setup the code properly for multiple domain tracking & subdomain tracking?

September 16, 2011 10:49 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@David: The code looks reasonable. The _setAllowHash method has been deprecated; it's no longer necessary for cross-domain tracking, but it doesn't hurt much to leave it in. It also looks like you'll potentially be tagging all outbound links, not just the ones to your other domain, but it is easier to implement this way than to check each link against the list of your domains before tagging.

The bump in average time on site makes sense because you're maintaining the session across domains whereas before the session would break as you moved from domain to domain. For example, if you spent 3 minutes on a.com, 3 minutes on b.com, and 3 minutes on c.com, your average time on site in the old model would be 3 minutes, but in the new model it would be 9 minutes.

September 16, 2011 11:27 AM

Nick Budden said:

Hi Jeremy,

Thank you for the great post, I've been search for something like this for quite some time. I'm running a Wordpress network using subdomain installs, and currently all of my sites are being tracked using a single profile. What I hope to accomplish is to have one profile that tracks my primary domain AND my subdomains, and also to have an individual profile associated with each of my individual subdomains. I have a relatively small number of subdomains, and can customize my code for each if needed (i.e. my wordpress users cannot create their own subdomains...the solution does not need to be very dynamic). What would you suggest as the best solution for this?

Again thank you for the article!

October 5, 2011 3:50 PM

Kamran Jamshidi said:

This has been bookmarked, informative and well explained.

Using: _gaq.push(['_addIgnoredRef', 'example-petstore.com']); to filter own things away is useful.

Same goes with search engine reports etc from analytics, you get more clean data using features like:
_gaq.push(['_addIgnoredOrganic', 'www.mydomainname.com']);

October 10, 2011 6:02 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

While it's possible to track everything with a single account number and create the profiles for individual subdomains using filters, it probably makes the most sense to set up a second tracker for each subdomain with a separate account number. The reason is that there are types of hits that cannot be easily excluded using filters, which would show up in all of your profiles unless you took additional measures. This behavior is not well-defined, so you are best off using separate accounts.

Note, however, that these can simply be sub accounts within your main GA account. The profile for your main site might use UA-12345678-1, while the profiles for your subdomains might use UA-12345678-2, UA-12345678-3, etc. Also, the code for each subdomain should probably have the same subdomain modifications as your global tracking code unless you have specific reasons for not doing so. This can help to avoid subtle issues like having global tracking code that includes a leading period on your main site along with tracking code just for the main site that has no subdomain modifications, but in fact includes subdomain tracking that does not use the leading period by default, resulting in a hash conflict.

October 11, 2011 8:04 AM

justin brock said:

Great article, Jeremy.

Google recently updated the subdomain tracking video on Conversion University. In it they advise the leading period. http://services.google.com/analytics/breeze/en/domains_subdomains/index.html

Is your advice still not to use the leading period for those of us who only have subdomains, as opposed to lower-level subdomains?

October 13, 2011 12:20 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Justin: Yes, I still prefer to not use the leading period in situations where there are no lower-level subdomains. Lower-level subdomains are the only situation where a leading period is required. Not including the leading period tends to result in more forgiving tracking code. If someone manages to put up a page without code or the incorrect code, if they launch a website optimizer test, or if they were previously not previously doing subdomain tracking and update their code to include subdomain tracking modifications--all of these situations are handled much better without the leading period.

October 13, 2011 1:35 PM

Dan Lyons said:

Hi Jeremy,

Here's the issue I'm trying to solve:

I have multiple sites with different product catalogues.

SiteA.com - primary site. All shopping cart conversions happen through here. It has multiple subdomains.

SiteB.com - separate domain with no subdomains, has online store. But when an item is "added to cart" on this site, it sends the visitor to SiteA.com to complete the purchase. There is a unique "added to cart" page on SiteA.com that a visitor only sees if they came from SiteB.com - think of it as SiteA.com/cart/SiteBcart-addedtocart. This means anytime we see a pageview of SiteA.com/cart/SiteBcart-addedtocart in the GA reports, it means they were on SiteB and added something into their cart.

We're collecting all data into one profile - this includes SiteA.com and its subdomains and SiteB.com. Code we're using on SiteA.com and its subdomains is as follows:

var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-123456-1']);
_gaq.push(['_setDomainName', 'sitea.com']);
_gaq.push(['_setAllowHash', false]);
_gaq.push(['_setAllowLinker', true]);
_gaq.push(['_trackPageview']);
_gaq.push(['_trackPageLoadTime']);

SiteB.com code:
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-123456-1']);
_gaq.push(['_setDomainName', 'siteb.com']);
_gaq.push(['_setAllowHash', false]);
_gaq.push(['_setAllowLinker', true]);
_gaq.push(['_trackPageview']);
_gaq.push(['_trackPageLoadTime']);

We've tagged all links sending someone from siteb.com to sitea.com with linkbypost.

The issue: while we're tracking visitors successfully on both domains and subdomains, it seems the cookie is getting dropped when an item is placed in the cart on SiteB.com. When I look in the content report and segment down everyone who saw SiteA.com/cart/SiteBcart-addedtocart (visitors I know could only have come from siteb.com to sitea.com after placing an item in their cart) and then use a secondary dimension to identify their source, I'm seeing them as referrals from SiteB.com. I would also expect their landing page to be somewhere on SiteB.com, but landing page is showing up as SiteA.com/cart/SiteBcart-addedtocart.

Would appreciate your thoughts on why the cookie might be getting dropped in this instance.

Thanks!

October 15, 2011 10:42 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Dan: When you tag the links from one domain to the other, the cookie information from the first domain is passed to the second domain through the query string. Oftentimes with carts, these query parameters can become corrupted or may be stripped from the final URL altogether. You would need to confirm that this isn't happening. If it is, then there may be a way to work around it, but it will likely be rather complicated.

October 17, 2011 8:47 AM

ryan said:

Great article. Now for the code you recommend.... Does that go on both the main url and the subdomain? Thanks. Ryan

November 2, 2011 2:10 PM

Kim K said:

If the link to open the subdomain opens in a new window, will that cause a new session to be started? I have the correct codes on the domain and subdomain, but I see that a cookie is being writtem for the subdomain and it doesn't contain the original referrer data. Want to tell my client that they should open the links to the subdomain in the same window. I have never run across this particular "flavor" of setup, although I have coded up dozens and dozens of cross domain tracking setups.

November 23, 2011 2:47 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Kim: Opening the subdomain in a new window should not affect cookies. If cookies are being written improperly, then that means there is some issue with the Google Analytics Tracking Code on the subdomain. Even if the code on the subdomain is correct, it's possible that Google Website Optimizer code, Google Analytics Tracking Code from another vendor, or 3rd party code with built-in Google Analytics Integration might create a second second set of cookies for the subdomain.

November 28, 2011 9:08 AM

Nate said:

Great Post. Quick question. We are tracking multiple subdomains and top level domains on one tag. I noticed a lot of self referrals and came across this post. But have discovered something else. My issue is with the subdomains. One subdomain did not get updated with the GA tag. It had no tag at all. This subdomain is commonly hit when passing between two other subdomains. With this tag being absent, how bad did we mess up our data over that time? So if the users path was as follows (and it always will be):

subdomainA.domain.com > subdomainB.domain.com > subdomainC.domain.com - what did this do to our data?

Obviously we got a referral from subdomainB when, and lost our correct referral information I assume, and did not get page views on subdomainB, but did we also inflate visit count? Did we get a visit when they landed on A and exit when they landed on B and then a new visit when they landed on C?

I know that's a little off topic of this post, but if you have some insight that would be great.

December 15, 2011 2:45 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Nate: In Google Analytics, a session ends when there has been more than 30 minutes between pageviews. When the session ends, this means that the next pageview will result in a new visit and that the referral information of the visitor is subject to being updated. If it's been less than 30 minutes, however, then the referral information will not update unless it's something other than a site referral (i.e. tagged or organic).

This means that you will only get self-referrals when the visitor has spend more than 30 minutes on subdomainB. This also means that whenever the source changes from something else to a self-referral, a new visit has resulted with a new landing page and the visit count has been inflated.

December 15, 2011 3:38 PM

Saul said:

Hi! Thanks for this useful article. I have a one domain and 2 subdomains with your code implementation. But I don't know how track visitors from one subdomain to another..I mean how many new visitors has come to a subdomain and then went to another subdomain for example.

Sorry for my english.

December 23, 2011 6:15 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Saul: This code is for tracking a domain and its subdomains as a single site. When this is implemented, traffic moving from one subdomain to another is not as visible as it would be with the default code. If it's more important for you to see the subdomains as separate sites, then it may be better to just stick with the default code. There are ways to set up two accounts in Google Analytics and track subdomains both ways, as separate sites and as a single site, but this can be tricky to get right. The main concern is that cookies will likely be shared on the main domain unless you make sure to always resolve to www and the account that tracks subdomains individually explicitly sets the domain name to the FQDN (e.g. _gaq.push(['t2._setDomainName', 'www.domain.com']); or _gaq.push(['t2._setDomainName', document.domain]);).

December 27, 2011 10:14 AM

Blanka said:

Hi Jeremy,

the article is great, although I still have troubles with setting the subdomains tracking. We have a big media site with multiple subdomains, but just one parent domain. After customizing the tracking code we got rid of self referrals, but we noticed a huge drop in pageviews, which just doesnt make sense to me. Is there any explanation of why that happens? The code was the following:

_gaq.push(['_setAccount', 'UA-XXXXXXX-1']);
_gaq.push(['_setDomainName', 'mydomain.com']);
_gaq.push(['_trackPageview']);

Thank you!

January 2, 2012 7:31 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Blanka: There shouldn't be a drop in pageviews, so that suggests a configuration issue. One possibility is that the _setDomainName code may be incompatible with some of the subdomains. For example, you might have mydomain.co.uk, or mydomain.someotherdomain.com. Also, if you have multiple levels of subdomains, such as sub1.sub2.mydomain.com, then you'll need to use .mydomain.com instead of mydomain.com. These types of situations all result in no pageviews being generated for the affected subdomain.

January 3, 2012 11:27 AM

Jens said:

Hi Jeremy,

Several days ago I submitted a comment. Since thena couple of other comments have been published, but not mine. Is there a chance my comment ended up in the spam list? I would be really interested to get your feedback on a couple of my questions...

Thanks, Jens

January 3, 2012 7:23 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Jens: I searched for your other comment, but I wasn't able to find it (not even in the spam list). If you wouldn't mind reposting your questions, I would be happy to answer them.

January 4, 2012 8:22 AM

AB said:

This is a very useful post.

A couple of questions:

We were previously using setdomain without a period before the domain name. When we adjusted the GA code for subdomain tracking we then ADDED a period inadvertently.

We noticed that both direct traffic and goal completions increased tremendously.

Is this because users were likely dually cookied and goal completions fired twice?

Thanks,

February 1, 2012 12:41 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@AB: I'm not sure why goal completions would go up, but switching from non-leading period to leading period causes a cookie reset, which results in an increase in direct traffic. Leading period and non-leading period cookies are completely incompatible; each destroys the other.

February 6, 2012 2:55 PM

AB said:

Paid traffic is also showing as direct. Would adding the leading period resolve this issue?

Thanks,

February 7, 2012 10:37 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@AB: Consistency is key. In most cases, it doesn't really matter whether or not you use the leading period, but it does matter that you do the same exact thing on every page of the site. If you have some pages with the leading period and some without, that will seriously affect tracking. Also, any other GA based script on the site needs to be consistent as well. For example, if you're running a GWO test on the site, the same modifications need to be made there as well, including urchin.js style modifications (i.e. _udn = ".example.com";). Sometimes third party scripts will include their own GA tracking, which typically needs to be disabled to avoid interfering with your own code.

Paid Traffic showing up as direct could also be a result of redirects stripping the tags or landing pages with missing or incorrect GA code. For AdWords, you also need to make sure that autotagging is enabled, that your Adwords and Analytics accounts are linked, and that cost data has been applied to all relevant profiles.

February 7, 2012 10:53 AM

Abhijeet Kotwal said:

Hi,

I have a website and a blog which I'm tracking using GA.

We are using following accounts to track the site and the blog (sub domain)

For the main website example.com: UA-1234567-1

For the blog.example.com: UA-1234567-2

The problem is currently, I have to see two separate GA reports and Google is treating Traffic separately.

What I need is, the traffic to the website and blog should be considered as a single source of traffic and
single Report where I can monitor Source, Audience, Content, etc.

P.S. The Website is hosted separately and blog is on WordPress.

Please suggest a solution.

Thanks
Abhijeet

February 9, 2012 4:05 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Abhijeet: You should change the code on the blog so that it uses UA-1234567-1 instead of UA-1234567-2. You'll also need to modify the code on both the blog and the main site for subdomain tracking. Usually this means adding a line of code immediately after the _gaq.push(['_setAccount', 'UA-1234567-1']); line that looks like this:

_gaq.push(['_setDomainName', 'example.com']);

The code may be different depending on the version of GA you have up on the site. If you're using a WordPress plugin for GA, there should be an option to specify the domain as "example.com". I believe it's called "Domain Tracking" under advanced settings.

February 9, 2012 8:48 AM

TW said:

First of all, thank you for this amazingly useful article. Good info is tough to find on this subdomain tracking topic.

My question: I am currently developing a new site (brand new) that will have upwards of 15 subdomains. Since a lot of your advice here deals with those who had previous (no leading period) setups, would you still recommend the no-leading-period setup to me even though I am starting new?

I'm simply trying to figure the best way to track all 15 subdomains in one profile while still able to differentiate between the subdomains in traffic reports.

Any advice is greatly appreciated - thanks!

February 9, 2012 11:56 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@TW: I still prefer no leading period for new setups as long as there aren't multiple levels of subdomains because it gives you a more forgiving setup. For example, a person may set up a Google Website Optimizer test on the site and forget to modify the code for subdomains. If you use the leading period, visitors who get entered into the test will likely have their cookies thoroughly thrashed, leading to invalid data in GA. If your site doesn't use the leading period, then while the GWO setup is not ideal, you have a greater chance of keeping your GA data intact. Similarly, if someone sets up another page or subdomain and forgets to add subdomain modifications to the tracking code, you're more likely to be OK if the rest of your site does not use the leading period than if it does.

As far as differentiating between subdomains in the traffic reports, you can do this for the most part using advanced filters. Advanced filters can let you see all the visits that touched a particular subdomain. It will also include pageviews from other subdomains if they were part of that visit.

If you need to distinguish between subdomains at the pageview level, then I would use an advanced filter to add a prefix to request uri indicating the subdomain. For example, you can set it up so that blog.example.com/index.html will show up in the reports as /blog/index.html. This can be done with a single advanced filter, or with multiple filters if you have longer subdomains that you want to shorten in the page-level reports.

February 9, 2012 12:25 PM

TW said:

Jeremy: Many thanks!

So, to make sure I understand your advice 100%, you're saying:

1) Set up tracking code on all 15 subdomains the same way:

//Tracking code customizations only
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-12345-1']);
_gaq.push(['_setDomainName', 'example-petstore.com']);
_gaq.push(['_addIgnoredRef', 'example-petstore.com']);
_gaq.push(['_trackPageview']);

2) Distinguish between subdomains at the pageview level through advanced filtering / custom reports

If you feel like giving me additional insight into the best way to set up that advanced filter, I'm all ears.

Thanks again!

February 9, 2012 3:55 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@TW: 1. Yes. 2. Advanced Segmentation and standard filters on the profile. The following is one way to set up the filters:

http://code.google.com/apis/analytics/docs/tracking/gaTrackingSite.html#profilesKey

February 10, 2012 8:28 AM

TW said:

Again: Many thanks!

February 10, 2012 2:50 PM

Abhijeet Kotwal said:

Hi,

Thank you very much for the help!

After your feedback I implemented the following code:

var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-1234567-1']);
_gaq.push(['_setDomainName', 'mydomain.com']);
_gaq.push(['_trackPageview']);
_gaq.push(['_setAllowAnchor', true]);

(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);
})();


I implemented this code for mydomain.com and blog.mydomain.com (both hosted seperately)

But after this code implementation the Bounce Rate has drastically jumped from 20%+ to 60%+... For most of the pages on mydomain.com existing pages.

Could you please tell me how do I fix this issue?


Thanks,
Abhijeet

February 13, 2012 11:33 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Abhijeet: Make sure you include _gaq.push(['_addIgnoredRef', 'mydomain.com']); as well. That's not likely the cause of the bounce rate increase, but it's worth adding regardless. It sounds like there may be some rogue code on the site that's no longer compatible with your main tracking code. You can use a tool like httpfox and see if more than one __utm.gif hit is being generated per page. If that doesn't turn anything up, check your browser reports and see if the bounce rate is affecting only one browser. If it's an IE issue, there are IE specific tools you can use to view hits and cookies to try to determine what's going on. If nothing else, it may be worth rolling back the code temporarily until you can determine what's going wrong in a test environment.

February 14, 2012 8:22 AM

Domenico said:

Hi Jeremy,

thanks for this great article.

I have got an issue: I have got an existing main domain (say example.com) which has been collecting data for a couple of years and I now need to set up a third level domain (say something.example.com) within the same UA. I've followed your instructions as far as the third level domain is concerned so the code looks like

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

and set up a brand new profile under Google Analytics with a filter as "Include only traffic from the domains that are equal to something.example.com"

I have modified the tracking on the main domain site as follows

_gaq.push(['_setAccount', 'UA-XXXX-Y']);
_gaq.push(['_setDomainName', 'example.com']);
_gaq.push(['_addIgnoredRef', 'example.com']);
if(condition == true)
{
_gaq.push(['_setCustomVar', 1, 'CustomVarName', CustomVarValue, 2]); // I need this for some special situations
}
_gaq.push(['_trackPageview']);

but the main domain tracking has immediately dropped to 0, while on the second profile has not been collected at all.

What have I done wrong?

Thanks,
Domenico

March 14, 2012 10:53 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Domenico: I don't see anything wrong with the code you've set up. The behavior sounds like there may be an issue with the domain string you're passing to _setDomainName. If this string does not match the root level domain, then your tracking won't work at all. This could be a typo, or perhaps using .net instead of .com or something along those lines. Also note that while with _addIgnoredRef you could pass just 'example' instead of 'example.com' without any ill-effects, the same is not true of _setDomainName.

As far as the filter is concerned, I generally don't trust any of the pre-built filters, but always use a custom filter with the correct regex. In this case, I'd use a custom include filter on the hostname field with a value of "^something\.example\.com$".

March 14, 2012 11:47 AM

Domenico said:

Unfortunately there was no typo and everything seemed correctly set up, at least to me.

I'll give it another try and hope..

Anyway, thanks for your help.
Domenico

March 14, 2012 1:33 PM

Matt said:

Jeremy,

Great post and seriously impressive that you've responded to every commenter! So here's another one: after implementing this code a few months ago I've reduced the amount of self referrers by about 97% BUT I'm still seeing enough to believe that something still needs to be tweaked. First question, can you every totally eliminate self referrers? Second, based on this code do you see any obvious problems or have any suggestions:

I have a www.domain.com and info.domain.com. Code is the same on both:


try { var pageTracker = _gat._getTracker("UA-1234567-1");
pageTracker._setDomainName("domain.com");
pageTracker._trackPageview();
var supplementalTracker = _gat._getTracker('UA-1234567-2'); supplementalTracker._trackPageview();
} catch (err) { }


notice that I'm also pushing data into a second profile as per a client's request. Finally I didn't use addIgnoredRef and if you think that's the solution please let me know.

Thanks

March 30, 2012 11:59 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Matt: I would use _setDomainName("domain.com") for supplementalTracker as well and use _addIgnoredRef("domain.com") for both. That should take care of any lingering self-referral issues.

I think it's possible, but very difficult, to eliminate all self-referrals. If there are a few lingering self-referrals that make up less than 1% of your overall traffic, especially if also less than 1% of key visits (e.g. converting visits), then it's probably not worth chasing down the remaining fraction of a percent. For complex sites, the bar may be higher than 1%.

March 30, 2012 1:01 PM

Matt said:

Thanks Jeremy! Can you provide some reasons why it may be impossible to remove all self-referrals. The only reason I can think of is old cookies from pre-cross domain tracking modification Visitors.

March 30, 2012 2:15 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Matt: That's one reason. Other reasons include cached pages or pages with old/rogue code.

March 30, 2012 3:22 PM

Maggie said:

Hi Jeremy,

Using your article, we recently updated our GA tracking code to the following:
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-111111-1']);
_gaq.push(['_setDomainName', '.domain.com']);
_gaq.push(['_addIgnoredRef', 'domain.com']);
_gaq.push(['_trackPageview']);

Now we need to implement cross-domain tracking as well. Should we just add the _gaq.push(['_setAllowLinker', true]); line, or we should remove the _addIgnoredRef?

April 5, 2012 7:29 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Maggie: Just add the _gaq.push(['_setAllowLinker', true]); line.

April 5, 2012 8:07 AM

Newbie said:

Hi Jeremy,

Thanks for the great article, it's quite a puzzle getting your head around all these settings to be honest. I'm currently reviewing a proposed implementation (below) which requires the referral data between subdomains to be captured in a separate account for each subdomain and the cross domain data to be captured in one overall account. Do you see any reason why this wouldn't work?


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



_gaq.push(['._setAccount', 'UA-xxxxxxx-1']);
_gaq.push(['._setDomainName', '.domain.com']);
_gaq.push(['._trackPageview']);

April 23, 2012 11:39 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

In order for this work, your main domain must resolve all requests to www.domain.com. If it can resolve/does resolve to just domain.com instead, then you will have cookie conflicts for those pages.

I would also recommend using the following instead:

var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-xxxxxxx-1']);
_gaq.push(['_setDomainName', document.domain]);
_gaq.push(['_trackPageview']);



_gaq.push(['._setAccount', 'UA-xxxxxxx-1']);
_gaq.push(['._setDomainName', '.domain.com']);
_gaq.push(['._trackPageview']);

Passing document.domain set cookies to fully qualified domain name without turning off cookie hashing. Passing 'none' also sets cookies to the fully qualified domain name, but it turns off hashing too. The hash allows the the code to determine the correct set of cookies to read from. When it's turned off, the code will read the first set of cookies it finds, which may be the wrong set.

Also, if you don't have any lower-level subdomains (e.g. my.sub.domain.com), and don't expect to have any, then you should use 'domain.com' instead of '.domain.com' This will make your code a bit more resilient if, say, someone puts some rogue code on the site or launches a Google Website Optimizer test.

April 23, 2012 12:19 PM

Jackye said:

Hi Jeremy..
It's so hard to make that works.
We have 2 sub-domains here, and when I put:

_gaq.push(['_setDomainName', '.example-petstore.com']);
_gaq.push(['_setAllowHash', false]);

It get a lot of self referrals. =/
But I didn't understand your suggestion quite sure..
So How can i do it?
Something like that:

_gaq.push(['_setDomainName', 'domain.com']);
_gaq.push(['_addIgnoredRef', 'domain.com']);
_gaq.push(['_trackPageview']);


What will happen with sub1.domain.com and sub2.domain.com? Should I put the same code? Or do I need to put a change on them too?

Thank you so much, these settings are so hard to understand =/

April 26, 2012 4:09 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Jackye: Yes, the code you posted should work:

_gaq.push(['_setDomainName', 'domain.com']);
_gaq.push(['_addIgnoredRef', 'domain.com']);
_gaq.push(['_trackPageview']);

You would use this same code on both sub1.domain.com and sub2.domain.com.

April 26, 2012 4:55 PM

Jackye said:

Thanks!

Another quick one:

Is there any really difference between this:

_gaq.push(['_setDomainName', '.domain.com']);
_gaq.push(['_addIgnoredRef', '.domain.com']);
_gaq.push(['_trackPageview']);

and this:

_gaq.push(['_setDomainName', 'domain.com']);
_gaq.push(['_addIgnoredRef', 'domain.com']);
_gaq.push(['_trackPageview']);

the "." before domain.com really matters?
our domain here is www.domain.com with subdomains: sub1.domain.com and sub2.domain.com

Thanks again!

April 27, 2012 8:51 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Jackye: Yes, there is a difference. If you use the leading period (the "." before domain.com), then your cookies will be set in such a way that they'll be accessible to lower level subdomains (e.g. lowersub1.sub1.domain.com). Most people do not have lower level subdomains, so this is usually unnecessary. Furthermore, cookies set without the leading period are more compatible with cookies set without any subdomain at all.

So if you have the option to not use the leading period, this is usually the way to go as it makes your code more resilient. For example, someone might launch a Google Website Optimizer test on the page without adding subdomain code, or you might use a 3rd party plugin that also happens to have Google Analytics tracking enable. With these types of situations, there's a greater chance that your tracking will be just fine if you don't use the leading period. Otherwise, both of these scenarios would result in a cookie conflict, with the end result being that your cookies would be destroyed and recreated with incorrect referral information.

For _addIgnoredRef, you should not use the leading period regardless of whether or not you use the leading period for _setDomainName. _addIgnoredRef does a straightforward string comparison between the current domain and the string you pass to it. So if someone can get to, say, domain.com without the www, then _addIgnoredRef won't catch it if it has the leading period. You can, in fact, simplify _addIgnored ref and just pass "domain" if you felt like it. Of course, this would potentially ignore domain.org or domain.net as well, but it's really just to illustrate the fact that _addIgnoredRef just checks to see if the string passed to it is a substring of the current domain.

April 27, 2012 9:35 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Jackye: Yes, there is a difference. If you use the leading period (the "." before domain.com), then your cookies will be set in such a way that they'll be accessible to lower level subdomains (e.g. lowersub1.sub1.domain.com). Most people do not have lower level subdomains, so this is usually unnecessary. Furthermore, cookies set without the leading period are more compatible with cookies set without any subdomain at all.

So if you have the option to not use the leading period, this is usually the way to go as it makes your code more resilient. For example, someone might launch a Google Website Optimizer test on the page without adding subdomain code, or you might use a 3rd party plugin that also happens to have Google Analytics tracking enable. With these types of situations, there's a greater chance that your tracking will be just fine if you don't use the leading period. Otherwise, both of these scenarios would result in a cookie conflict, with the end result being that your cookies would be destroyed and recreated with incorrect referral information.

For _addIgnoredRef, you should not use the leading period regardless of whether or not you use the leading period for _setDomainName. _addIgnoredRef does a straightforward string comparison between the current domain and the string you pass to it. So if someone can get to, say, domain.com without the www, then _addIgnoredRef won't catch it if it has the leading period. You can, in fact, simplify _addIgnored ref and just pass "domain" if you felt like it. Of course, this would potentially ignore domain.org or domain.net as well, but it's really just to illustrate the fact that _addIgnoredRef just checks to see if the string passed to it is a substring of the current domain.

April 27, 2012 9:35 AM

Rita said:

I'm trying to understand this (eek) and set up my GA. I have a .com site such as: www.bookstore.com and on that same domain have added www.bookstore.com/blog. (wordpress) What I don't understand is; is the blog considered the subdomain? And would I put the .com site as the domain and leave the blog as the subdomain? Or would I put the .com/blog and leave the main .com as the subdomain ? Then, what exact code would I add to the generated code so that it would all track properly ? Thanks for keeping it simple. :)

June 1, 2012 12:44 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Rita: What you have is a subdirectory. There's no special code needed in order to track your subdirectory in addition to your main site. The standard GA code should work fine.

If your wordpress blog was on blog.bookstore.com, instead of www.bookstore.com/blog, then you would have a subdomain and would need to modify your code.

June 1, 2012 1:21 PM

Rita said:

@Jeremy, okay my website is a eg. www.bookstore.com and my blog is www.bookstore.com/blog so you said that would make it a subdirectory and no need to update the code. Good. So, my question is; what do I put in the profile settings URL and the property settings URL would I only ever need to put eg; www.bookstore.com and then the .com/blog part would automatically pick up in the stats ? So, should property and profile URL's match ? That is what I need to know to finish signing up with my proper settings. Thanks so much!

June 3, 2012 1:22 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

GA does not consider a subdirectory to be a separate site, even if the hosting for that subdirectory is different for the rest of your site. It will pick up on your subdirectory automatically. If you decide to create a profile that only reports on your blog subdirectory, you will need to add a filter to that new profile to only include traffic to that subdirectory. The profile name should probably include the subdirectory as well, only to be able to distinguish it from your main profile, but the subdirectory does not need to be included as part of the URL, and you should not create a new web property for the subdirectory, but rather use the existing web property for your main site.

June 4, 2012 8:50 AM

Nathan Arthur said:

Hello, Jeremy!

I've got a question for you: Will subdomain tracking work when the main domain and the subdomain use different versions of the GA tracking code? I'm using an eCommerce service (store.mydomain.com) which uses legacy ga tracking code, whereas my main site (mydomain.com) uses the new asynchronous version.

The problem I'm trying to fix is that any traffic that came from my main site, to the store, and then ended in a purchase, shows as direct traffic. The original referral data isn't being preserved.

My modified code looks like this:

mydomain.com/.org code:

var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-xxxxxxx-y']);
_gaq.push(['_setDomainName', 'mydomain.com']);
_gaq.push(['_addIgnoredRef', 'mydomain.com']);
_gaq.push(['_addIgnoredRef', 'mydomain.org']);
_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);
})();

store.mydomain.com code:

var pageTracker = _gat._getTracker('UA-xxxxxxx-y');
pageTracker._addDevId('o5cUG');
pageTracker._setAllowLinker(true);
pageTracker._setDomainName('none');
try{pageTracker._setDomainName('mydomain.com');
pageTracker._addIgnoredRef('mydomain.com');
pageTracker._addIgnoredRef('mydomain.org');}catch(e){};
pageTracker._trackPageview();

What am I doing wrong?

June 14, 2012 2:21 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Nathan: You can use different versions of the GA tracking code on different pages. The issue you're having is that visitors are going from a .org site to a .com site. This is a cross-domain situation, which means that you'll need to modify your code for cross domain tracking:

https://developers.google.com/analytics/devguides/collection/gajs/gaTrackingSite

More specifically, you should not have both _setDomainName('none') and _setDomainName('mydomain.com'). I would use the latter on both mydomain.com and store.mydomain.com, and use _setDomainName('mydomain.org') on mydomain.org. You should also include _setAllowLinker('true') on all three sites and make sure to use _link or _linkByPost as appropriate on any links or forms that go from .org to .com or vice versa.

June 15, 2012 8:30 AM

Nathan Arthur said:

Thank you so much for the reply!

So .org is just an alias of our .com address. Anything available on the .com is available on the .org. Is there a way to make Google Analytics play nice with this, and not have to worry about tracking then like they were two different sites? Would using only "_setDomainName('mydomain.com');" achieve that?

I would really like to avoid having to worry about cross-domain tracking if at all possible. We've even thrown around the idea of just setting up a site-wide 301 redirect from .org to .com if it would take the cross-domain aspect out of the picture. I'd rather not have to resort to that, though.

June 18, 2012 8:59 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Nathan: 301 redirecting from .org to .com would avoid the cross-domain situation. Alternatively, you could also have a store.mydomain.org in addition to store.mydomain.com. Then you would just need to be consistent with your links and maintain separate tracking codes for the .org and .com sites, since the _setDomainName line would be different for the .org and the .com sites.

There are also scripts which can be used to tag all of the links going between the two domains. It's still considered cross-domain, but it can take some of the pain out of the setup. It's also not too hard to write your own script, especially if you already have a JavaScript library like jQuery on the site. The trickest part is getting such scripts to work for edge cases such as links and forms with multiple redirects and things like that. If you have full control over all sites, then you may be able to eliminate those types of situations if any exist, which can greatly simplify cross-domain tracking.

June 19, 2012 8:06 AM

Stuti said:

Thank you so much for this.
Made my day
God bless you :)

July 30, 2012 1:55 PM

vincent said:

hi Jeremy:

i have also encounted the self-referral issue, and should it add the the modify code "_gaq.push(['_addIgnoredRef', 'sister-site.com']);" to all pages in each subdomain? or add only one statement in the front page

November 2, 2012 11:16 PM

vincent said:

hi jeremy

i also have the self-referral issue, and i followed your instrcution adding the modified code :"_gaq.push(['_addIgnoredRef', 'sister-site.com']);"
in each pages of our maindomain. but the problem still exist.

should i add the modified code for each pages under each subdomain? or just add only a statement on the front page of our main domain?

as u menetioned in our article :"This also eliminates the need to add a separate _addIgnoredRef statement for each subdomain."

so confused..

November 3, 2012 12:00 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@vincent: You should add the same modification to all subdomains as well.

There is a common misconception that you need to add a separate _addIgnoredRef statement for each subdomain:

// BAD EXAMPLE
_gaq.push(['_addIgnoredRef', 'www.sister-site.com']);
_gaq.push(['_addIgnoredRef', 'blog.sister-site.com']);
_gaq.push(['_addIgnoredRef', 'shop.sister-site.com']);

Instead, only one line is necessary site-wide, regardless of how many subdomains you have:

// GOOD EXAMPLE
_gaq.push(['_addIgnoredRef', 'sister-site.com']);

Note also that the official documentation still recommends:

// BAD EXAMPLE
_gaq.push(['_addIgnoredRef', 'www.sister-site.com']);

which is still wrong since it won't match requests for your domain without the 'www', nor for subdomains.

November 5, 2012 7:55 AM

Jasmina said:

Hello

I want to track www.example.com and not other subdomains, e.g. static.example.com. To that effect I've tried setting _gaq.push(['_setDomainName', 'www.example.com']); but this is not working out as the cookie is still set to example.com so it's also set for static.example.com

How would you recommend that this is implemented so that the cookie is only set for www.example.com and not for static.example.com or any other subdomain?

301 redirect is in place for example.com to www.example.com

November 7, 2012 6:23 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Jasmina: The line you're adding should work, so if you're having trouble with it, make sure you're adding it after the _setAccount line but before the _trackPageview line.

November 8, 2012 7:51 AM

Jasmina said:

Ta Jeremy, it became obvious as soon as I read your comment.

November 8, 2012 4:27 PM

Poulpator said:

Hi,
I have more than 200 subdomain.
And a need to know each unique visitor per subdomain.
Is there a way to view data per subdomain without creating a profile for each subdomain?

Regards from French Alps

November 20, 2012 11:36 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Poulpator: You can set up a custom report with Hostname as a dimension and unique visitors as a metric.

November 20, 2012 3:29 PM

Chris Eldredge said:

are any recommendations in this article now out of date?

thanks for the great article!

May 21, 2013 4:34 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

The code modifications recommended by this article for subdomain tracking are still up to date for ga.js.

May 22, 2013 8:09 AM

Pavel said:

Jeremy, sorry if this has already been answered before, but I couldn't find it in the 3 years of comments to this topic, so would appreciate if you could help me out.
We have a website with 3 language versions.
www.website.com for english
lang1.website.com for lang 1
lang2.website.com for lang 2

Currently we have a default tracking code installed which results in inflated visits, recorded under Referral section of google analytics.

Do we understand this correctly that adding
_gaq.push(['_addIgnoredRef', 'website.com']);
would eliminate those self-referrals?

So if originally the user came from Google to a www-version and then switched to lang1., then with the updated tracking code, Google Analytics would report that visit as a single visit originating from Google but would include two Domain Names under this visit which were visited by the user.

Hmmm, but then, that would be two visits, no?

Do you know, how would such a visit be reflected in the GA-report?

December 6, 2013 12:03 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Pavel: Assuming you're still using ga.js analytics, you will need both lines:

_gaq.push(['_setDomainName', 'website.com']);
_gaq.push(['_addIgnoredRef', 'website.com']);

December 9, 2013 12:42 PM

anna-lisa said:

Hi Jeremy, thanks for your helpful post. I have a question: I have a cross domain & subdomain issue, site A with subdomain A1/A2/A3 and so on, and the conversion/transaction occurs on Site B. I have set a duplicated complete profile for all visits to site A with a filter which includes all visits coming from subdomains. Then I have set single profiles for each subdomain with a filter including visits from each subdomain (filter Host name). On these single profiles I can't see any conversion/transaction. I presume it's because the filter includes only visits from subdomain, so visits (and conversions) from Site B are excluded.

Am I right? Is there a way to solve this problem?

February 28, 2014 5:38 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

If you track all of the domains and sub domains in a single view/profile, then you should be able to create custom advanced segments for each subdomain. Any filter solution would likely require a complicated set of 3 filters based on an indicator on Site B that lets you know which sub domain it's currently being used for.

March 3, 2014 9:04 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

If you track all of the domains and sub domains in a single view/profile, then you should be able to create custom advanced segments for each subdomain. Any filter solution would likely require a complicated set of 3 filters based on an indicator on Site B that lets you know which sub domain it's currently being used for.

March 3, 2014 9:04 AM

Damion said:

Brilliant! I just wish this post was written..... er, the last time I needed to have this as a reference! I had to cobble together a fix from those various inadequate, outdated, fuzzy articles you mention.

I've bookmarked this, and hopefully I'll remember its existence next time the sound of dying tracking is all around. Devs all too often give little thought to how tracking might be affected by their "quirky" subdomain (or even multi-domain) structure, and I'm hoping that this article might be able to solve a few problems before they spiral out of control. Thanks once again!

January 5, 2011 5:13 PM

Eric Polatty said:

If you go to the tracking code section under profile settings in your GA account, and click "one domain with multiple subodmains" under "what are you tracking", I notice the code Google generates for you to use does not include the _setAllowHash tag. But they tell you to include it in the Google Code article for subdomain tracking. I understand it's a free product - but I find Google's inability to make up their minds about how to use their own software frustrating to say the least.

January 6, 2011 9:51 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Eric: My guess is that the Google Code example includes _setAllowHash because it is on a page dedicated to cross-domain tracking. Unfortunately there's currently no Google Code page that just deals with subdomain tracking. I think we lost this during the transition from the traditional ga.js code to the async code, but I'm hopeful that this will be addressed.

The code that's generated from your Google Analytics account is better, but still suffers from the other issues I went over. The lack of an _addIgnoredRef line, or rather the lack of the logic behind the _addIgnoredRef line being executed for an appropriate _setDomainName call, is especially disconcerting since it implies that _setDomainName is sufficient for optimum subdomain tracking.

January 6, 2011 10:37 AM

Eric Polatty said:

@Jeremy - Most of the main Google Code article is on cross-domain situations, but there is a section "tracking across a domain and it's sudomains" and it has the _setAllowHash tag there.

January 7, 2011 10:26 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Eric: It's possible that since it was sandwiched between the other cross-domain examples that the _setAllowHash tag was added unintentionally. Regardless, it shouldn't be there for a subdomain only example.

January 7, 2011 10:32 AM

Mike Sullivan said:

Thank you! Thank you! Thank you!

We added (yet another) subdomain to our environment over the holidays and I tried (yet again) to get rid of the self-referrals. There's so much not-quite-right guidance out there!

Made your suggested changes and today, they have dropped WAY off!

January 7, 2011 11:50 AM

Adam said:

Great article. I'd just about given up on solving the self referrals issue.

Question: if your site uses both subdomains and lower level subdomains, should you use a leading period on both, or just your lower level subdomain pages?

January 7, 2011 12:05 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Adam: If your site has lower level subdomains, then you should use the leading period site-wide.

If you used the leading period on some subdomains and not on others, the hash codes for the cookies would be different, so your cookies would get destroyed every time you crossed from a page using the leading period to a page not using the leading period and vice versa. So regardless of whether you decide/need to use the leading period or not, you want to be consistent.

January 7, 2011 2:09 PM

david said:

Hi Jeremy,

This article of yours was definitely a nice reading.

I experienced myself lots of issues a few weeks ago when adding subdomain tracking to our site, following Google instructions. One of the main problems was a huge boost of direct traffic (we were using leading period, but we didnt use SetAllowHash).

I am willing to try your solution now. However, would you still recommend this implementation (no period and AddIgnoreRef) even for the traditional ga.js code?

January 10, 2011 7:20 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@David: Yes, I would recommend this solution even if you're using the traditional ga.js code. This would look something like the following:

var pageTracker = _gat._getTracker("UA-12345-1");
pageTracker._setDomainName("example-petstore.com");
pageTracker._addIgnoredRef("example-petstore.com");
pageTracker._trackPageview();

A sudden influx of direct traffic can result from going from no subdomain tracking to subdomain tracking with the leading period. Removing the leading period may help, but this depends on how long you've had the code with the leading period up. There aren't any hard or fast rules on this, but I would say that if you've only had the code with the leading period up for a month or more, you might be better off sticking with it at this point.

There's nothing inherently wrong with using the leading period. The main issue I have with it is that for a site that the hash code generated when you use the leading period is different than the one generated when you don't have subdomain tracking at all. If you've already been using the leading period for a significant amount of time, then switching your code to not use the leading period may be just as bad for tracking as switching to using the leading period in the first place.

Also, for a brand new Google Analytics installation, using the leading period is perfectly fine.

January 10, 2011 8:02 AM

David said:

Thanks for your advice, Jeremy. I will keep your considerations in mind and try your proposed subdomain tracking code.

We had the code with the leading period for just a couple of days. The breakage of the data was big enough to get quickly back to the older version, even though it was not taking into account the existing subdomains.

Hopefully I will get a chance to try your suggestions some day next week. Our site has a large amount of traffic, so after a few hours we will be ready to say if it is working or not. I will let you know ;)

January 10, 2011 10:19 AM

Cloga said:

Excellence article!Thank you!

January 10, 2011 10:46 AM

Cristina Chetroi said:

Hi Jeremy!
The _addIgnoredRef tip to minimise self-referrals is great, as they really are a pain. Thanks!

I also remember someone mentioning the inconsistency between the code GA console generates for subdomain tracking (no setAllowHash to false) and the official documentation.

We all wish domain hashing needn't be compromised. But the reality is that it often is - it's common that a client decides to introduce subdomains or other domains at a later stage and you need to tweak the snippet as the result.

So, when it happens, would it be possible to introduce some sort of cookie checkup for returning visitors and do some sort of merge instead of setting a second set cookies/destroying them?

January 12, 2011 5:19 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Cristina: It would certainly be possible to do that. I've done something similar to that before with cookies that were generated with _setNamespace, so it shouldn't be that hard. I have some other ideas about how this might be done as well, something I'm hoping to write about in a future post.

January 13, 2011 7:54 AM

Liz said:

would i use this customization on all subdomains and the top level domains? Or just all the subdomains I want to track - I will have about 4 or 5 of them.

Thanks

January 27, 2011 2:27 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Liz: I would recommend using the modification on all subdomains and top level domains. I have seen some cases where people wanted to track certain subdomains only so they could see traffic coming from other subdomains as referrals, but this is not an ideal setup. Inevitably someone also wants to track the other subdomains, which gives you strange mix of referrals from subdomains and original referral data to those subdomains showing up in your reports. Instead, you should track everything and use filters in Google Analytics to exclude the unwanted domains.

January 27, 2011 4:26 PM

Bernd said:

You wrote:
_gaq.push(['_setDomainName', 'example-petstore.com']);

Google says:
_gaq.push(['_setDomainName', '.example-petstore.com']);

(see the dot before domainname).

What is the difference?

January 30, 2011 2:16 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Bernd: The main differences are that:

1. Each generates a different hash, but not including a leading period has the same hash as no subdomain tracking at all.
2. Including a leading period works for sites with lower level subdomains (ex. buy.store.example-petstore.com).

Google includes the leading period to account for #2. The reason I don't include the leading period is because of #1. It feel that it's more likely that someone is transitioning their code from no subdomain tracking to subdomain tracking than that they have lower level subdomains.

So, as mentioned in the article, if you have lower level subdomains, or if you're setting up Google Analytics Tracking Code on your site for the first time, use the leading period. If you don't have lower level subdomains and you've had Google Analytics Tracking Code on your site for a while, then don't use the leading period.

January 31, 2011 7:54 AM

Bernd said:

OK, thank you very much, Jeremy!

January 31, 2011 1:33 PM

Nick said:

I'm a little confused. Your second point says that you have to use the leading period if you have lower level subdomains, but then at the end you said don't use if you don't have to.

Let's say I have example.com and store.example.com, would I want to use the leading period to track this properly?

January 31, 2011 5:52 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Nick: The only time you have to use the leading period is if you have lower level subdomains. For your example, the leading period is unnecessary for tracking this properly because you don't have any lower level subdomains. You'd have to have another level of subdomain tacked on to there, such as buy.store.example.com.

If you don't have lower level subdomains and you're setting up Google Analytics for the first time on a site, then you have the option to either use or not use the leading period. I tend to not use it as this tends to be more stable, again because the hash code is the same as if you didn't have subdomain tracking on the main domain. So if someone else sets up a Google Website Optimizer test on your homepage, for example, and forgets to add subdomain tracking modifications, this isn't as big of a deal if you had implemented subdomain tracking without the leading period.

The main benefit to using the leading period for new sites without lower level subdomains is that you'll have less people question your setup since it's closer to the Google recommendations.

For sites with existing Google Analytics Tracking Code that you want to update to use subdomain tracking code, not using the leading period will lead to a much smoother transition. Of course, if your site also has lower level subdomain, you'll have to bite the bullet and use the leading period anyway.

Whichever way you decide to go, make sure that you apply that decision consistently across your site. Having some pages that use the leading period and some that don't will wreak havoc on your site.

February 1, 2011 7:56 AM

Chris said:

I'm working on a WordPress MultiSite project which uses subdomain, some of which are mapped to other domains. So what I'm doing really is more in line with the Google example since its not just sub-domain tracking but cross-domain tracking. My question to you is is there any benefit to using _addIgnoredRef for cross-domain tracking? Or could it hurt in any way? I'm looking to reduce self referals as much as possible.

February 4, 2011 12:21 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Chris: Using _addIgnoredRef will still help some with preventing self-referrals. You should have one _addIgnoredRef statement for each root level domain. _addIgnoredRef only ignores a referral if there is previous referral data to fall back on.

So if you have any links between domains that aren't tagged with the proper linking parameters, this will show up in your reports as self-referrals, even if you use _addIgnoredRef. This is a good thing, because it provides visibility for fixable self-referrals.

If there is previous referral data, however, _addIgnoredRef will preserve it. This can be especially useful in situations where you can tag links to a third-party domain, but have trouble tagging links going back to the original domain.

February 4, 2011 8:33 AM

Rob said:

I tried using Google's subdomain tracking suggestion to no avail. For 1 day I did see in GA URL's from the subdomain but I have not been able to figure out how. I came upon this blog after discussing this with a GA expert who has been gracious enough to help us try a few options.

So I adjusted the subdomain code to look like this, per your suggestions:

var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-xxxxxxx-y']);
_gaq.push(['_setDomainName', 'cae-nyc.org']);
_gaq.push(['_addIgnoredRef', 'cae-nyc.org']);
_gaq.push(['_trackPageview']);


The primary/main Drupal-driven domain has this:


var _gaq = _gaq || [];
_gaq.push(["_setAccount", "UA-xxxxxxx-y"]);
_gaq.push(['_setDomainName', 'cae-nyc.org']);
_gaq.push(['_addIgnoredRef', 'cae-nyc.org']);
_gaq.push(["_trackPageview"]);

Now, a thing to note: we have 2 URL's that we use, hosted on a share GoDaddy account: caenyc.org and cae-nyc.org. (Notice a hyphen). The subdomain does NOT have a hyphen it' all advocacy.caenyc.org. I do not have access to an Apache httpd.conf file so I have to use GoDaddy's GUI/Total Domain Control to create the redirect. Could that be causing the problem? Can you peak at both domains & view their source?

Thanks!

Rob

February 8, 2011 9:44 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Rob: Your code should be different depending on which domain it's on. So on cae-nyc.org (with the hyphen), your code should look like the following:

var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-xxxxxxx-y']);
_gaq.push(['_setDomainName', 'cae-nyc.org']);
_gaq.push(['_addIgnoredRef', 'cae-nyc.org']);
_gaq.push(['_trackPageview']);

But on caenyc.org (without the hyphen), your code should look like the following:

var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-xxxxxxx-y']);
_gaq.push(['_setDomainName', 'caenyc.org']);
_gaq.push(['_addIgnoredRef', 'caenyc.org']);
_gaq.push(['_trackPageview']);

The value you pass to _setDomainName must match the domain it's on, otherwise the code will fail. This is also true when you're tracking both example.com and example.net.

I also don't know if visitors can go back and forth between cae-nyc.org and caenyc.org. If they can, then that falls under the realm of cross-domain tracking, which requires a completely different set of tracking code modifications. Still, you'll need to fix the _setDomainName line on caenyc.org to get any kind of tracking there at all.

February 8, 2011 1:03 PM

Rob said:

Sigh, I wish I had tried the obvious yep that worked. And yes people can go from the sub-domain to the main domain and vice verse.

So for example, an email campaign might start with the sub-domain. Then a person fills out the form on the sub-domain, and clicks on Home, which goes back to the main www domain.

Or, people will click on a link from www, e.g., on the home page, and go to the sub-domain, fill out the form, and may hit home. Does that mean cross-domain?

Also, using the sub-domain filter, the Content report is showing the paths with a leading / like this:

/advocacy.caenyc.org/site/apps/kb/cs/contactsearch.asp

or

/advocacy.caenyc.org/site/c.rwL4JlO7KzE/b.6421085/k.DF6F/Petition_to_Incoming_Schools_Chancellor_Cathie_Black/apps/ka/ct/contactus.asp?c=rwL4JlO7KzE&b=6421085&en=ftINKXMILiKPJ5PUJeILI3OLInKZI7OKJgIXK6OQKtK9F


I take it I can transform the URL with another filter?

February 8, 2011 4:53 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Rob: You only need to implement cross-domain tracking if a visitor can move across root level domains. Going from avocacy.caenyc.org to www.caenyc.org does not count as cross-domain because you're just moving from one subdomain of caenyc.org to another.

Going from avocacy.caenyc.org to www.cae-nyc.org, however, does count as cross-domain tracking and requires additional modifications to your code, as well as modifications to the links going between domains. Generally it's something to be avoided if at all possible.

In your situation, the easiest way to avoid the issue is to just 301 redirect visitors who request cae-nyc.org pages to the appropriate caenyc.org page. This eliminates the need for cross-domain tracking and dramatically simplifies your Google Analytics setup.

With regard to filters, yes, you can apply additional filters after the subdomain filter. Those filters will be applied to the modified URL instead of the original URL, so you can use this to change the URL to look exactly how you want it to in Google Analytics. Also, you may want to look at Exclude URL Query Parameters under the Main Website Profile Information to remove any unnecessary query parameters and clean up reporting even further. This is usually easier than using filters to remove the query parameters.

February 9, 2011 7:57 AM

Emily said:

I have multiple domains that I have the same UA# (cookmedical.com, cookbiodesign.com and cookartlab.com). These domains feed traffic between each other and so it would be helpful if I could track them as if they were all the same site to track users between the domains. Based on this information it sounds like I should add the following to all of the pages in all the domains:

_gaq.push(['_setDomainName', 'none']);
_gaq.push(['_addIgnoredRef', 'cookmedical.com']);
_gaq.push(['_addIgnoredRef', 'cookbiodesign.com']);
_gaq.push(['_addIgnoredRef', 'cookartlab.com']);

Am I understanding you correctly?

February 9, 2011 8:48 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Emily: The _addIgnoredRef lines may help with some self-referrals issues, but they're not directly related to cross-domain tracking.

Cross-domain tracking in Google Analytics is the sort of thing that really deserves a series of posts, but I'll try to summarize it as best as I can within this comment.

First, I generally avoid using _gaq.push(['_setDomainName', 'none']); because it does too much. _gaq.push(['_setAllowHash', false]); (no quotes around false) accomplishes the minimum for cross-domain tracking, so it's preferred.

Second, you'll also need to add _gaq.push(['_setAllowLinker', true]); (again, no quotes around true).

Third, you'll need to modify the links between domains. The easiest way to do this is to have the following onclick attribute in the link:

onclick="_gaq.push(['_link', this.href]); return false;"

This covers most scenarios, but not all of them. There will likely be additional nuances that these instructions won't handle. The official Google Code article may help with some of these.

Here are some other things to keep in mind:

1. _link invokes a javascript redirect, which means the referrer won't be available on the receiving page in IE. There are other ways to do this that preserve the referrer, but they are more advanced.
2. _linkByPost may work with forms that use GET instead of POST, but you'll have to specifiy true in the third parameter, that is:

_gaq.push(['_linkByPost', this, true]);

This passes query parameters through the anchor text instead of the query string. This means you'll also need to add _gaq.push(['_setAllowAnchor', true]); to your Google Analytics Tracking Code.
3. It's generally preferred to accomplish linking between domains in a more dynamic way. You might be able to build this into a template driven site, or use a script that modifies onclick attributes of links dynamically.
4. You should try to minimize redirects between domains. These will often do unintended things to query parameters and anchor text and make cross-domain tracking very difficult or impossible.

Because of all the complications involved in cross-domain tracking, you may want to consider purchasing a support plan to ensure that everything is set up correctly.

February 9, 2011 9:18 AM

Emily said:

Thanks that helps a lot. I talked to my developer about this and we're building a dynamic script to add the onClick function to the links that are moving between domains that we want to track together.
I agree that it would be best if we didn't have this highly related content on different domains and we are in the process of redesigning our overall site to include the pages that are currently on separate domains. In the mean time we really need to be able to see how users are moving through our sites.

Thank you for all your help!

February 9, 2011 10:44 AM

Eduardo Cereto said:

The argument that the leading dot can cause problems when you're changing a GA implementation is valid. But what's not clear in the post is your opinion about new implementations.

Since a new implementation doesn't have any already set cookie we should bother, than I think there's no drawback about using the leading dot.

I always use the leading dot in my new implementation, and will keep doing so.

I'm not only worried about the sub-sub-domains. But the leading dot feels more compliant with the RFC that specifies that the absence of it can cause Rejection of the cookie. I'm not sure how many browsers acctually comply to that statements, none I know of. Still I'd rather not take my chances.

http://www.ietf.org/rfc/rfc2109.txt

Quoting the RFC:
4.3.2 Rejecting Cookies
...
* The value for the Domain attribute contains no embedded dots or
does not start with a dot.

[page] 4
Domain=domain
Optional. The Domain attribute specifies the domain for which the
cookie is valid. An explicitly specified domain must always start
with a dot.

February 10, 2011 10:32 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Eduardo: I think that you can argue it either way for new Google Analytics implementations. I prefer not to use the leading period even for leading implementations (assuming of course that there aren't any sub-sub-domains). The reason is that this type of setup tends to be more forgiving when it comes to things such as rogue Google Website Optimizer tests where someone forgot to add subdomain tracking modifications.

If the RFC were an issue, then it seems like Google would have addressed this in the standard Google Analytics Tracking Code. As stands right now, if you don't do any subdomain tracking at all, then the cookies are set without the leading period. So this leads me to believe that it's a non-issue at least as far as cookie compliance is concerned.

Either way you approach this, you're going to have exceptions:

1. If you default to using the leading period, then anytime you add subdomain tracking on a site that already had Google Analytics implemented, then you'll have to consider how much of a negative impact using the leading period is going to have and possibly not use it.
2. If you default to not using the leading period, then anytime you add subdomain tracking you'll have to make sure/hope there aren't any sub-sub-domains.

For me, I find that the exceptions for #2 crop up far less frequently than for #1. Not only that, handling the exceptions for #2 is pretty cut and dry, whereas handling those for #1 involve much more of a judgment call.

Also, to be perfectly honest, I've always felt more comfortable not using the leading period. It's always felt like the right way to do it. It seems to lead to safer setups. But I can easily see how someone could have started out always using the leading period and so instead they feel more comfortable using, it feels right, it seems safer. So I'm OK with someone taking the #1 approach to it instead, but I'll probably continue taking the #2 approach.

February 10, 2011 12:49 PM

Steffen said:

Hey Jeremy, thanks for your post. Very interesting.

I'm facing the following problem: with a few days gap after deploying your recommended tracking setting, traffic from a referring subdomain drops significantly. Expected effect on _addIgnoredRef(). Meanwhile, direct traffic increases. That - in turn - is not what I expected and in my case not supposed to be. What's the benefit from tracking subdomain traffic as direct traffic? That's even more confusing than tracking as referring. I expected that traffic to become "internal" traffic. How to achieve that?
And why is that gap from ... say 10 days?

Thanks in advance.

February 24, 2011 7:56 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Steffen: I can't determine the exact cause without seeing the code or looking at the site, but if traffic from a subdomain is showing up as direct, then that indicates some type of code inconsistency between the main domain and the subdomain. Here are some things to consider:

1. Are you wanting to track the main domain and the subdomain together? Sometimes people want to track these separately, or they don't want to/can't track the subdomain for some reason and want it tracked as a referring source. This article assumes that you do want to track them together.

2. If you're tracking the main domain and the subdomain together, then the Google Analytics Tracking Code on each should be very similar, if not identical. In particular, the _setDomainName and _setAllowHash statements (or lack thereof) must be identical. You can't have a leading period on one and not on the other, use _setDomainName("none") on one and not on the other, or use _setAllowHash("false") on one and not on the other.

3. Are you running any Google Website Optimizer tests on either the main domain or the subdomain? Similar to #2, the Google Website Optimizer code must have the same set of modifications as your Google Analytics Tracking Code. This is fairly straightforward for the tracking script and conversion script, but the control script needs to be modified using equivalent urchin.js style modifications.

4. Is there any other Google Analytics Tracking Code on any of the pages? This includes legacy code, code put there by someone else for some other purpose, or even UTM code for Urchin. Any extra code like this will need to either be modified to match your Google Analytics Tracking Code or removed.

February 24, 2011 8:20 AM

Cory said:

Hi Jeremy,

This is such a great article. I recently spent a lot of time scratching my head over some self-referrals until we saw this.

I quickly implemented your code as outlined above on a simple (/path/page.aspx) www domain and a developer added matching script on a more complex transaction subdomain(pages.aspx?pid=000 etc)

Unfortunately, I'm able to see only traffic that moves from the "complex" (www) site to the "simple" (subdomain) site but not the other way around.

What do you think that means? On which CMS should I look to edit?

Thank you!

February 24, 2011 1:08 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Cory: My previous comment most likely applies here as well. In particular, you should check both sites for legacy Google Analytics Tracking Code that might have a different set of modifications than the code you just added. The legacy code will then have to either be modified or removed.

February 24, 2011 1:20 PM

Peter O'Neill said:

Hi Jeremy,

Just had a long discussion with an ex-colleague about _addignoredref and want to clarify what the impact of it is.

In point 3 of the blog, you recommend using it to avoid self-referrals when a visit session expires between pageviews. That makes sense but I can't see this causing a high percentage of self-referrals. For most sites, this should occur a minimal number of times. If a site has many visits timing out (maybe due to video), would suggest increasing length of visit.

Instead won't using this code eliminate recording of all self referrals as they will all be reported as the previous referrers or as Direct? As you say in one of the comments, this information can be useful for finding untagged pages or untagged links between subdomains.

Thanks - Peter

March 4, 2011 6:25 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Peter: Pages with a lot of content or videos can certainly exacerbate the issue, but self-referrals will often make up 1 to 2 % or more of traffic even on sites without videos or long sales letters.

I'll speculate on why and say that in general, we often don't have a captive audience on the web. Someone may be on one site, think of something and open up a tab to check something on another site, or maybe they notice they have an email, or maybe they get a phone call, etc. Depending on the type site, they may also be doing comparison shopping and have 10 different tabs open at once.

Regardless of why this is happening, _addIgnoredRef is a nice solution because it only applies to visitors that have previous referral data available. This means that a visitor won't just show up as direct instead of a self-referral, unless of course they were previously direct.

A new visitor who starts at an untagged page and moves to a tagged page will still show up a a self-referral, even if you're using _addIgnoredRef. Eventually this will happen for enough visitors that you'll see the problem in your Google Analytics reports.

This is especially true of untagged landing pages, but a page not designed to be a landing page will usually still end up as a landing page for enough people to point out the problem in Google Analytics. But if you still have the 1 to 2% of noise coming from self-referrals that could have easily been prevented by _addIgnoredRef, it makes it much harder to catch these pages.

Even if self-referrals only showed up for true problems, I'd still use _addIgnoredRef because it's more important to preserve referral information when possible than to fix a problem on a single page. If the page is important enough, then the tagging issue on that page will become obvious at some point anyway, even without a bunch of self-referrals to point it out. If it's not a very important page, then the misfortune of having that page missing from your reports is still outweighed by the benefit of having correct referral information for those visitors who spent a little too long on that page (or the previous page) for whatever reason.

March 4, 2011 7:57 AM

Peter O'Neill said:

Thanks for the detailed reply. I hadn't realised the degree to which self-referrals are driven by visitors timing out - that does change the situation.

I also agree with your logic on using _addIgnoredRef based on how you have described it as working. However that appears to be different to the Google description (which I know is wrong occasionally). They say

Excludes a source as a referring site. Use this option when you want to set certain referring links as direct traffic, rather than as referring sites. For example, your company might own another domain that you want to track as direct traffic so that it does not show up on the "Referring Sites" reports.

This suggests that all traffic from the domain specified will be reported as Direct. As opposed to what you have written which is it will pick up the previous referrer for returning visitors and have no affect on new visitors. Have you found that this is the way it works in practice and that this is another example of where Google needs to update their documentation?

March 4, 2011 12:49 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Peter: Yes, I would say that the Google documentation on _addIgnoredRef is a bit misleading. In practice, it works as I've described it.

March 4, 2011 1:07 PM

Peter O'Neill said:

Ok, that explains my confusion. Thanks for the assistance and the detailed explanations given.

March 4, 2011 1:26 PM

Rene said:

Very useful information and i did understand it until you mentioned crossdomain tracking needing a different approach with:
_gaq.push(['_setAllowHash', false]);
_gaq.push(['_setAllowLinker', true]);

What if you want to track example.com, store.example.com and example2.com together.So this would be Tracking Across Multiple Domains and one Sub-domain.

Would you use the following?

example.com
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-12345-1']);
_gaq.push(['_setDomainName', 'example.com']);
_gaq.push(['_setAllowHash', false]);
_gaq.push(['_setAllowLinker', true]);
_gaq.push(['_addIgnoredRef', 'example.com']);
_gaq.push(['_addIgnoredRef', 'example2.com']);
_gaq.push(['_trackPageview']);

store.example.com
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-12345-1']);
_gaq.push(['_setDomainName', 'example.com']);
_gaq.push(['_setAllowHash', false]);
_gaq.push(['_setAllowLinker', true]);
_gaq.push(['_addIgnoredRef', 'example.com']);
_gaq.push(['_addIgnoredRef', 'example2.com']);
_gaq.push(['_trackPageview']);

example2.com
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-12345-1']);
_gaq.push(['_setDomainName', 'example.com']);
_gaq.push(['_setAllowHash', false]);
_gaq.push(['_setAllowLinker', true]);
_gaq.push(['_addIgnoredRef', 'example.com']);
_gaq.push(['_addIgnoredRef', 'example2.com']);
_gaq.push(['_trackPageview']);

March 15, 2011 5:31 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Rene: The code for example2.com should be a little different:

var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-12345-1']);
_gaq.push(['_setDomainName', 'example2.com']);
_gaq.push(['_setAllowHash', false]);
_gaq.push(['_setAllowLinker', true]);
_gaq.push(['_addIgnoredRef', 'example.com']);
_gaq.push(['_addIgnoredRef', 'example2.com']);
_gaq.push(['_trackPageview']);

It'd important that the _setDomainName call match the root level domain of the site the code is on. If it doesn't match, then no cookies will be set and you won't get any Google Analytics data for those pages.

March 15, 2011 7:51 AM

Jeff said:

What if I want to track all of my subdomains independently? How do I set that up?
Each of my clients will have a branded website for themselves that I am hosting as a subdomain. I need to be able to generate a report showing Client A his traffic without any other clients info in there.
Currently we only have about 8-10 of these clients but the number is growing and could reach into the hundreds.
Any suggestions for this GA challenged guy?
Thanks in advance!
Jeff

March 28, 2011 4:19 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Jeff: See the comment at the end of the this post.

March 28, 2011 5:03 PM

Jeff said:

Thank you! I didn't realize there was a different post and kept looking at this one for a reply.
Thank you again!

March 30, 2011 12:59 AM

anobre said:

Hi there!
I've implemented this tracking code style and it seems to be working great with a catch. Now when i go , for instance, to top content report and click 'visit link' i'am always sent to the top domain when in most cases i should be redirected to a subdomain.

Cheers,

April 14, 2011 3:11 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@anobre: You'll need to add two steps to this:

1. Add a filter to add the hostname to the beginning of the request uri. Usually I use something like this:

Filter type: Custom Filter (Advanced)
Field A: Hostname
Extract A: (.*)
Field B: Request URI
Extract B: (.*)
Output to: Request URI
Constructor: $A1$B1
Field A Required: Yes
Field B Required: Yes
Override Output Field: Yes

2. Edit the Main Website Profile Information and change the Website URL to:

http://

This won't fix the existing data in your profile, but going forward, clicking on a link will go to the correct subdomain. This works for sites with multiple domains as well.

April 14, 2011 3:44 PM

Ryan said:

Hi Jeremy - great post. I was trying to follow along your comment discussion with Rene about cross-domain with sub-domain tracking but believe I missed something.

If I am tracking from www.mainstore.com (or mainstore.com) to 3rd party checkout which is a sub subdomain: checkout.sub.main.net - is what I have correct:


Site (mainstore.com):
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-XXXXX']);
_gaq.push(['_setDomainName', '.mainstore.com']);
_gaq.push(['_setAllowHash', false]);
_gaq.push(['_setAllowLinker', true]);
_gaq.push(['_setAllowAnchor', true]);
_gaq.push(['_addIgnoredRef', 'mainstore.com']);
_gaq.push(['_trackPageview']);


3rd Party (checkout.sub.main.net):

var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-XXXXX']);
_gaq.push(['_setDomainName', '.main.net']);
_gaq.push(['_setAllowHash', false]);
_gaq.push(['_setAllowLinker', true]);
_gaq.push(['_setAllowAnchor', true]);
_gaq.push(['_addIgnoredRef', 'mainstore.com']);
_gaq.push(['_addIgnoredRef', 'main.net']);
_gaq.push(['_trackPageview']);


Does that look correct (assuming the linker tags are in place)?

April 14, 2011 4:30 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Ryan: That code looks fine. The one thing I would add is that the _setDomainName call is optional for the third party domain unless you're tracking across subdomains on the third party domain. That is, if a visitor goes from your site to checkout.sub.main.net and doesn't see any other subdomains on main.net, then there's no need to do subdomain tracking for the third party domain.

Also, if you have two sites, one with sub subdomains and the other without sub subdomains, technically you only have to use the leading period on the site with sub sub domains. So even if a visitor could go from checkout.sub.main.next to somewhere else on main.net, that doesn't mean you need a leading period for mainstore.com as well.

As discussed in the article, you can certainly still include the leading period if you feel strongly about it, but there are benefits to not using the leading period which you might be able to take advantage of. It might also be difficult to remember which sites you have to use it for and which you don't, in which case always using the leading period may make more sense.

April 14, 2011 4:52 PM

Ryan said:

Great, I will try taking out the leading periods. Thank you Jeremy

April 14, 2011 4:55 PM

Brian Moore ? said:

Some thing tells me I ruined/fubar'd my analytics.

ok I have a ecommerce site using a 3rd party shopping cart.

my analytics code is this:
mysite.com

var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-*********-1']);
_gaq.push(['_setDomainName', 'none']);
_gaq.push(['_setAllowLinker', true]);
_gaq.push(['_setAllowHash', false]);

3rd party cart
cart.com

var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-********-1']);
_gaq.push(['_setDomainName', 'none']);
_gaq.push(['_setAllowLinker', true]);
_gaq.push(['_trackPageview', 'insert_page_name']);


ever since i implemented this code change so my boss could get the google adwords conversion tracking working the main site shows up as a referrer and now the ecommerce conversion rate in google analytics has droped to zero.

help please.

April 19, 2011 1:35 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Brian: I don't see a _trackPageview call for the mysite.com analytics call, but you may have just left that off. It's also not necessary to have both _gaq.push(['_setDomainName', 'none']); and _gaq.push(['_setAllowHash', false]); on the mysite.com code. You should probably drop the _setDomainName call.

My best guess is that you probably had some sort of linking in place that is now broken as a result of updating your code to the async version. Without knowing anything else, the easiest way you can probably fix that is to add the following after your Google Analytics Tracking Code:

_gaq.push(function() {
window.pageTracker = _gat._getTrackerByName();
});

You can add this after both your mysite.com code and your 3rd party code, assuming that the 3rd party domain links back to your main domain correctly.

April 19, 2011 2:45 PM

Ryan said:

Hi Jeremy,

Unfortunately I am still getting mostly (direct) transactions in my reporting. About 1/3 do contain the referring keyword so I believe I must be on the right track but am perhaps missing something.

This is with a Yahoo! store and I believe I have to the two links tagged correctly that point to the cross-domain from sunshineyoga.com to checkout:(yahoo.net).

Can I pay you to review at my implementation (via view source) to make sure I have the cross links tagged?

When I run through in WASP it looks like the cookie retains all the data so I'm not quite sure what the issue is.

Thank you!

April 20, 2011 11:01 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Ryan: We no longer offer stand-alone Google Analytics support plans. You should look into using Monitus in order to track Yahoo Store. That is what we always recommend for tracking Yahoo Store.

April 20, 2011 12:20 PM

Ryan said:

Do you have anyone you can refer me to?

Not really interested in having to pay monthly for GA data.

Thanks!

April 20, 2011 2:37 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Ryan: Monitus is the only viable solution for tracking Yahoo Stores. So if you don't want to pay monthly, you'll probably want to look into using something besides the Yahoo Store.

April 20, 2011 3:01 PM

Dan said:

If my sub domains have no reference or relationship to the TLD, would I not get valid results if I treated the sub domain the same as a TLD?
I setup a site in a WP multi site environment so wouldn't I just treat the sub domain the same as a TLD, generate and implement analytics the same way I would for a TLD?
Dan

May 2, 2011 10:34 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Dan: If the subdomain does not refer to the main domain and vice versa, then you do not need to implement subdomain tracking. The standard Google Analytics Tracking Code will work fine for both sites. You can either use separate account numbers (within the same Google Analytics account) to track each domain separately, or use the same one if you want roll-up reporting.

The same goes for multiple domains as well. If you have multiple domains and no domain links to any of the other domains, then there's no need to implement cross-domain tracking. The standard Google Analytics Tracking Code will work fine for all sites. And again, you can track the sites separately or in a roll-up profile (or both).

May 4, 2011 8:03 AM

Eric W said:

Hi Jeremy - great article. I recently added similar code in an attempt to fix self-referrals for our websites. The result was partially successful, they dropped dramatically for April (implemented 3/31).

However, we also experienced a massive unexplained drop in Visits and UV's, while our PV and every other performance metric increased.

Is there any reason that getting rid of self-referrals would lower UV's (or, to phrase properly, improperly having self referrals would have been inflating UV counts?)

Thanks,
Eric

May 9, 2011 9:20 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Eric: Self referrals will usually result in inflated visit counts. Inflated UV counts are less common, but this is also possible depending on what your code looked like before. Unique visitor counts are largely based on the __utma cookie remaining intact. So if your Google Analytics Tracking Code setup results in this cookie being recreated, then you will get an artificial spike in UVs.

May 10, 2011 7:59 AM

Eric W said:

Thank you very much! I was able remove my fix and test it and actually see the Unique Visitor ID change, creating extra UV's. Appreciate your feedback!

May 10, 2011 11:06 AM

Eric said:

Another question for you Jeremy.

Our sites have 1 main domain and 1 main subdomain. We get a ton of self referrals and corrected some of them by adding 1 missing line of code to our main domain pages.

However, we are still getting quite a few.

Here is the code we are using. Is this correct?


var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA of Main Page']);
_gaq.push(['_setDomainName', '.ericsite.com']); (this line was missing and was added 5 weeks ago, fixing about 60% of our self referrals)
_gaq.push(['_trackPageview']);

_gaq.push(['_setAccount', 'UA of rollup account']);
_gaq.push(['_setDomainName', '.ericsite.com']);
_gaq.push(['_trackPageview']);
_gaq.push(['_setAccount', 'UA of another rollup account']);
_gaq.push(['_setDomainName', '.ericsite.com']);
_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);
})();

May 12, 2011 4:30 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Eric: As mentioned in the post you should also add the following line for each account:

_gaq.push(['_addIgnoredRef', 'ericsite.com']);

This line can go right after the _setDomainName line for each account. Also note that I intentionally left out the period in front of ericsite.com. This is correct regardless of whether you use a leading period with _setDomainName or not.

May 12, 2011 4:45 PM

Eric said:

Thanks again, will report back results!

May 12, 2011 9:14 PM

Eric said:

Greetings again -

The addition of that code has had no impact. If we had our sites live for a solid 6 months with a subdomain issue, is it possible/likely that the remaining self-referrals we still see after fixing things are simply "baked" in to cookies and not fixable until the cookie expires?

Very much at a loss now.

Thanks again!
Eric

May 23, 2011 7:46 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Eric: Yes, it may take some time to work itself out. Not only do you have return visitors who already have cookies for self-referrals, but you also potentially have return visitors who are viewing cached pages with the old code that may still have their referral information overwritten with a self-referral.

Also note that this code change doesn't address other fixable sources of self-referral traffic. For example, if you have a landing page that's missing the tracking code altogether, the code change won't fix those self-referrals, but you can still fix the issue by adding the tracking code to that landing page.

May 24, 2011 7:13 AM

Eric said:

Couple more things.

#1 - I've had one site that has been fixed for 3 months now (2/22 fix date). That being the case, I'd expect their remaining self-referrals to be slowly dropping off over time. However, they are staying pretty flat since the initial drop from my 2/22 fix. That concerns me.

#2 - I added the hash setting to the site I tried your suggestion on last week. It now looks like this :
var _gaq = _gaq || [];
_gaq.push(['_setAccount', '']);
_gaq.push(['_setDomainName', '.ericsite.com']);
_gaq.push(['_addIgnoredRef', 'ericsite.com']);
_gaq.push(['_setAllowHash', false]);
_gaq.push(['_trackPageview']);


While the addition of addIgnoredRef last week had no impact on the self-referral count, the addition of setAllowHash false seems to have had a definite impact in lessening the self-referrals.

Does that make any sense to you?

Are there any drawbacks to turning off the hash like that?

Thanks again!
Eric

May 25, 2011 2:02 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Eric: Turning the hash off would cause a cookie reset for all your return visitors. So while this does remove all of the lingering self-referrals, it also removes all of the referral attribution for all of your return visitors. Most likely you're now seeing a jump in direct traffic.

May 26, 2011 7:37 AM

Eric said:

Yep - that's exactly what happening. Direct jumped from 32% to 49%.

Is the cookie reset from turning off hash a 1 time thing?

In other words, if I leave it as is, are the cookies being constantly reset for the same user over and over?

Thank you sooo much for the assistance. Invaluable.

May 26, 2011 1:48 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Eric: The cookies will only be reset a maximum of once per user, and only for users visited the site prior to the code change. For new visitors, the cookies will be set correctly for the first visit and will not be reset for subsequent visits (though of course standard attribution rules apply).

May 26, 2011 3:16 PM

Jonathan said:

Hi Jeremy - fantastic post, I've been looking for a way to fix our self-referral issue for a very long time.

Before I implement the changes you suggest (i.e. add addIgnoredRef) , a quick question about leading periods:

We've been using Google Analytics across multiple subdomains (but no lower level domains) for over a year, and have always used setDomainName with a leading period. I know you generally recommend not to use the leading period when making the "switch" to subdomain tracking, but what would you do in our situation, given that we've already used the leading period in setDomainName for such a long time?

Thanks for your help!
Jonathan

June 1, 2011 12:58 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Jonathan: If you've been using the leading period the whole time, then you're probably better off sticking with it. The main exception would if you've often had cookie corruption due to things like poor Google Website Optimizer implementations. In that case, moving to not using the leading period would still cause an initial cookie reset, but might prevent additional cookie resets down the road.

June 1, 2011 5:31 PM

Doug Gebhardt said:

What an amazing post. Thanks so much Jeremy. Looks like it has kept you hopping! I'm wondering about what happens when www2 is showing up in my referral traffic as the number 1 referrer. Would this help to eliminate this sort of self referral? Here is what we have right now.
var pageTracker = _gat._getTracker("UA-1234567-1");
pageTracker._setDomainName(".sample.ca");
pageTracker._setAllowLinker(true);
pageTracker._setAllowHash(false);
pageTracker._trackPageview();
Based on your other answers here, the leading period should be removed in the setDomainName as well to prevent the subdomains as showing up as referrers.
Cheers!

June 5, 2011 9:44 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Doug: The main reason for leaving off the leading period is that it creates cookies that are compatible with the standard, unmodified Google Analytics Tracking Code on your main domain. If you're using the leading period and already have for a while, then switching will cause a cookie reset. Also, whether or not you use the leading period does not affect whether or not you have self-referrals.

Adding the following line should help with some of the self-referrals:

pageTracker._addIgnoredRef("sample.ca");

As mentioned in the post, the leading period should not be used for this method, regardless of whether or not you use it in your _setDomainName call. This call can go right after _setDomainName call.

It's always possible that there may be some other reason why you're getting self-referrals, but this addresses one source of self-referrals caused by subdomain tracking in general.

June 6, 2011 7:26 AM

Devendra Singh said:

Quite informative post, especially because it even tries to correct some documentation mistakes of GA.

A small query please:
We have couple of websites on subdomains. Each one does its own SEO to attract Search Engine Traffic. The Visitors may land to any of the subdomain websites from Search Engine Referral. Later if the Visitor clicks a link to move to the sister subdomain, we still see the original source as the Referral Site. That's okay. But, is there a way to track that how many referrals were transferred to each other (without event tracking)?

Thanks,

DS

July 3, 2011 12:19 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Devendra: You could probably do this to some extent with custom variables or internal site search tracking. Another option would be to use a second tracking object. This would look something like this:

_gaq.push(['_setAccount', 'UA-XXXXXXX-1']);
_gaq.push(['_setDomainName', 'mydomain.com']);
_gaq.push(['_trackPageview']);

_gaq.push(['t2._setAccount', 'UA-XXXXXXX-2']);
_gaq.push(['t2._setDomainName', document.domain]);
_gaq.push(['t2._trackPageview']);

The idea here is that the first tracking object will have its cookies set to the root level domain, while the second tracking object will have its cookies set to the entire domain, including the subdomain. Some key things to notice:

1. Two separate accounts are used (UA-XXXXXXX-1 and UA-XXXXXXX-2).
2. 'mydomain.com' is a string while document.domain is not
3. This will only work reliably well in single domain with subdomain situations.
4. For the same reason as #3, do not use _gaq.push(['_setAllowHash', false]); even if you see documentation that says that you need to for subdomains.

July 5, 2011 7:45 AM

Ruby said:

Hi Jeremy, thanks for writing the article. It is very useful. I am new to GA. I have few questions about subdomain tracking.

I have a website site with sub.example.com and subsub.sub.example.com. The subsub.sub.example.com is not a brand new site so I should use

_gaq.push(['_setDomainName', '.example.com']);

to allow leading time for the site. With the dot in front of the domain name. Is it correct?

The code below should be in both sub.example.com and subsub.sub.example.com sites:

var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-12345-1']);
_gaq.push(['_setDomainName', '.example.com']);
_gaq.push(['_addIgnoredRef', 'example.com']);
_gaq.push(['_trackPageview']);

Also there is another subdomains under the same domain name, for example abc.example.com and efg.example .com. Will the code above track traffic from the other sub domains as well?

Many thanks

July 13, 2011 9:40 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Ruby: Your code looks correct. Because you have multiple levels of subdomains (e.g. subsub.sub.example.com), the leading period is strictly necessary. The same code works for just one level of subdomains (e.g. abc.example.com). The addIgnoredRef call is also correct; no leading period gives you the best coverage since this is simply a substring match using indexOf.

July 14, 2011 10:52 AM

webzdev said:

Hello Jeremy thnak you very much for your post. It was like hell for me to clarify to myself what is right and what is wrong.

I have following situation:
A year ago I did set up GA on a domain example.com BUT code looks like this:
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-xxxxxx-y']);
_gaq.push(['_setDomainName', '.example.com']);
_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);
})();

now I created a subdomain sub.example.com created a separate Profile in GA dashboard. Now I have 2 profiles for site url example.com. I copied GA code suggested by google, pasted it on sub.** but code looks like tihs:
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-xxxxxx-y']);
_gaq.push(['_setDomainName', '.example.com']);
_gaq.push(['_trackPageview']);
(it is the same as this on my main domain) I notice in dashboard there are different profile IDs but they are not addressed in the GA code.

I am confused what exactly should I do to track my subdomain AS A FULLY INDEPENDENT site.
Should I add sub.example.com as new site so I receive a different code or should I retain the second profile with some adjustments??

July 24, 2011 12:25 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

When you add a new profile, you should select the option to add the profile for a new domain rather than an existing domain. This will give you an account number that's separate from your existing profile. Note, however, that the only difference between the two account numbers will be the "-y" at the very end of the number. This is sufficient to track the sites separately.

Also, since you're tracking this subdomain separately, you may want to consider removing the _setDomainName line, to avoid sharing cookies between this subdomain and your existing site.

July 25, 2011 9:16 AM

Vikas Sahdev ? said:

Hi Jeremy,
You are the recognized GA expert here, so I would ask your advice. In between reading multiple threads, I am sort of confused and want to clarify whether what I am doing is correct.

I have two sites: www.example.com and a subdomain www.blog.example.com

What I want is:

1. Sub domain tracking

2. One GA Profile which tracks both the main domain and sub domain.

3. Conversion funnel from all pages on the www.blog.example.com to www.example.com

This is what I have done so far:


1.
I added the below code to www.example.com and www.blog.example.com:

var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-XXXXXX-1']);
_gaq.push(['_setDomainName', 'example.com']);
_gaq.push(['_addIgnoredRef', 'example.com']);
_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);
})();

2.

Created one Master Profile in GA( for www.example.com) without any filters


3.

Created a duplicate of the Master Profile in GA( for www.example.com) with the subdomain filter described earlier in the thread.


Below are the Questions I have:

1. Does the above set up look correct considering what I want to achieve?
2. It has been a day since I set up the second profile but still don't see any visits. Any ideas if something is wrong?
3. I want to implement a funnel whereby i want to track how many visitors from anywhere on www.blog.example.com came to www.example.com. Both the sites don't have default pages in the url( i.e no www.blog.example.com/default.aspx e.g). So in the funnel, how do i define step1 and step 2 urls since both sites have "/" as their default page?

4. Since both the profiles I have contain data from both sites, how do I "filter" reports for one site vs the other? For e.g I woudl like to know the unique visitors to only the blog site and not the main domain site. Is that possible?


Thanks a ton for your help looking into this.


July 29, 2011 5:32 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

Your best bet is to probably use an advanced filter for visits that include both hostnames. You could set this up as a goal, but it would only be useful if you checked the required step box, and even then only within the Funnel Visualization report. When you have a filter that modifies the request uri, the Goal URL and Funnel Steps should match the modified request uri instead, which means that you can do a head match on blog.example.com and www.example.com. The main thing to check if there's still no data is that the other profile is a duplicate of the other one, that is, the web properties should be the same. It's easy to create another profile that uses a -2 instead of a -1 in its Google Analytics Tracking Code.

August 1, 2011 5:29 PM

Vikas Sahdev ? said:

Thanks Jeremy. I have two more questions from your original article:

1. _gaq.push(['_addIgnoredRef', 'example.com']);

If I put the above line in the GA code, both for root domain and subdomain, would I still see the traffic coming from www.blog.example.com to www.example.com. Since I would like to track conversion from the blog site(sub domain) to main site( root domain), I don't want to loose the referrals from blog site to main site.

What reports exactly get impacted by using the code line above? Is it only the Reffering sites report?


2. _gaq.push(['_setDomainName', 'example.com']);

We had a separate GA ID for the subdomain and root domain and thus separate profiles in GA for each of those and we were using leading period in the setDomainName. This was happening for over a year.

Recently we started using the same GA ID for the subdomain and root domain and one profile for both sites with the cross domain filter applied.

In this situation, do you recommend that we keep the leading period or remove it in the above line of code ?

I am also confused by your original comment in the article which says "What this means is that if you weren't doing subdomain tracking previously".

I am not sure what exactly constitutes "doing subdomain tracking" to be able to say whether that condition applies to us. What I am doing is summarized in the previous post. Does that constitute what you meant by "doing subdomain tracking"?


Thanks again!!

August 9, 2011 7:01 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Vikas: _addIgnoredRef is a soft ignore, that is, it only ignores the referrer if there is pre-existing referral information. For example, if your tracking code is set up so that someone starting on the blog and moving to the main domain is counted as a blog referral, then adding _addIgnoredRef won't change that. If instead someone starts on the main site, moves to the blog, then moves back to the main site, then they will not count as a blog referral, even if they spent more than 30 minutes on the blog, because there were already cookies on the main site.

If you were previously using the leading period with _setDomainName, it's probably best to continue using the leading period unless you've been having problems. For example, if someone keeps setting up GWO tests and they can't remember to add proper subdomain tracking modifications, dropping the leading period might help alleviate some of those issues.

"Doing subdomain tracking" refers to using _setDomainName to share cookies across subdomains, regardless of whether you used the leading period. If you have subdomains, but you're not using _setDomainName, then you're not doing subdomain tracking because each subdomain is more or less being treated as a separate site.

In your scenario, it sounds like you want to be able to see traffic that's referred from the blog. In that case, using any form of _setDomainName doesn't make sense because you don't want the cookies to be shared between the two subdomains. _addIgnoredRef probably isn't a bad idea though since it will only give the blog credit when they came to the blog first. You won't easily be able to tell which keywords that sent visitors to the blog resulted in conversions on the main site, however, since those conversions will be credited to the blog instead of the keyword.

August 10, 2011 7:34 AM

Darius said:

Hi,

I tried this but it doesn't work. It still double counts visits over sub-domains, but now it just comes through as all direct. (I implemented it on a website which gets no traffic - so it was a controlled test).

The implementation suggested on the GA website also doesn't work. It ends up with loads of self-referrals.

August 11, 2011 5:47 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Darius: It's hard to know what the issue is without seeing the site. Normally with something like this I would use a cookie viewer like firebug with firecookie and a headers viewer like httpfox so I can see exactly when the issue occurs. Usually you can just use some fake tags like http://www.example.com/?utm_source=test&utm_medium=test&utm_campaign=test and then see when the cookies change to direct.

It may be that there's some rogue code on the page that doesn't have proper subdomain modifications that's causing the issue. This code could be legacy code that's still on the page, Google Website Optimizer code, or possible urchin Urchin UTM code.

August 11, 2011 7:53 AM

Tauseef said:

Hi Jeremy,

Thanks for the information. I update the code to track sub domain and domain traffic. I have two top level domain mobile.customizedstickers.com
blog.customizedstickers.com

The one I am more want to see not as a referral traffic is mobile cause I get conversion from that (Paid and Organic). After changing the code Now getting traffic as a direct.

Any idea why it's doing it or just a old cookies kicking in.

Any help will be highly appreciable.

Thanks in advance.

Tauseef

August 11, 2011 5:16 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Tauseef: Most likely the direct traffic is return traffic to the site. Because both of your domains are subdomains, the cookies by default would have been at the subdomain level. Now that you've implemented subdomain tracking, cookies will be read and created at the root level domain. This means that you may lose information for returning visitors. Over time, this number should decrease and the percentage of direct traffic should go down.

August 12, 2011 9:43 AM

Owen Smith said:

Hi Jeremy,

Perhaps you can help me out with an issue I'm having.

I have a website like so: mysubdomain.x.x.ca

I store static content (css, js, etc) at: static.mysubdomain.x.x.ca

Now, I don't want cookies to get set on the static subdomain for caching purposes.

On my pages, my tracker looks like :
var _gaq=[
['_setAccount',''],
['_setDomainName', 'mysubdomain.x.x.ca'],
['_trackPageview']
];

However the cookies are still set as ".mysubdomain.x.x.ca"

Can you provide any insight on not including lower-level subdomains?

August 14, 2011 2:54 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Owen: If you explicitly need cookies to not be available for any other domains, then you'll need to use something like this:

_gaq=[
['_setAccount',''],
['_setDomainName', 'none'],
['_trackPageview']
];

Then the cookies will only be available to the domain they were set on. Note that this will also affect the hash, so you need to be careful to check that this works as you expect it to. Also, it might be best not to explicitly set _gaq to an array. _gaq is only temporarily an array; it's later rewritten as an object. So it might not always work as expected.

August 15, 2011 8:05 AM

Ken Holden said:

Would this work for issues regarding a secure subdomain? The site is www.planetdj.com. The user is sent to secure.planetdj.com upon beginning check out. (Feel free to see for yourself).
This is the current code we have implemented.


var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-605157-1']);
_gaq.push(['_setDomainName', 'none']);
_gaq.push(['_setAllowLinker', true]);
_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);
})();

All of our conversions are listed as (direct) / (none).

It's not a referral issue, which is why I ask.

Your help would be awesome. Thanks! Great article!!

August 24, 2011 5:02 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Ken: I would recommend something along these lines:

var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-605157-1']);
_gaq.push(['_setDomainName', 'planetdj.com']);
_gaq.push(['_addIgnoredRef', 'planetdj.com']);
_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);
})();

These modifications will track visitors as they move across subdomains of planetdj.com. As long as everything is on planetdj.com, there's no reason to implement cross domain tracking modifications (_setDomainName('none') or _setAllowHash(false), _setAllowLinker(true), etc.).

August 25, 2011 7:28 AM

Ken Holden said:

Yeah that still didn't work. Would there be interference with the cookies? All our conversion traffic is still labeled as (Direct)/(none).

Care to take a peek? Feel free to start the checkout process, as I feel that's where the issue starts.

August 25, 2011 5:28 PM

HopeThisHelps said:

Note that _setAllowHash() has now been deprecated:

http://code.google.com/apis/analytics/docs/gaJS/gaJSApiDomainDirectory.html#_gat.GA_Tracker_._setAllowHash

and the recommendations on the Google site are now a lot closer to the above. I think they are listening ;-)

September 9, 2011 4:14 AM

David said:

Here is the situation our websites share a main navigation / design thus you can easily navigate between 'www.a.com', 'www.b.com' and 'www.c.com' we also have two subdomains of 'www.a.com' that each website uses for quotes & sales those subdomains are: 'secure.a.com' and 'sale.a.com'.

So if you are on 'www.a.com' and click a main navigation item you could go to 'www.b.com' once there say you add an item to your shopping cart you are take to 'secure.a.com'

Here is the solution we have implemented:

On each domain / subdomain we have placed this code:

_setDomainName is the only thing that changes and reflects the domain or subdomain you are on i.e. in this case ".a.com" on the other domains / subdomains it reads ".b.com", ".c.com", ".secure.a.com" and ".sale.a.com".

var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-XXXXX-1']);
_gaq.push(['_setDomainName', '.a.com']);
_gaq.push(['_setAllowLinker',true]);
_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);
})();

$('a').click(function() {
var url = $(this).attr("href");
if (url)
{
if (url.substring(0, 4) == 'http' && url != '' && url != '#' && url.toLowerCase().indexOf('youtube') {
if (url.substring(0, 4) == 'http')
{
_gaq.push(['_link',url]);
location.href = url;
}
return false;
}
}
});

Here are the questions:

We have noticed a large bump in average time on site, why, and how do we correct this?
Have we setup the code properly for multiple domain tracking & subdomain tracking?

September 16, 2011 10:49 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@David: The code looks reasonable. The _setAllowHash method has been deprecated; it's no longer necessary for cross-domain tracking, but it doesn't hurt much to leave it in. It also looks like you'll potentially be tagging all outbound links, not just the ones to your other domain, but it is easier to implement this way than to check each link against the list of your domains before tagging.

The bump in average time on site makes sense because you're maintaining the session across domains whereas before the session would break as you moved from domain to domain. For example, if you spent 3 minutes on a.com, 3 minutes on b.com, and 3 minutes on c.com, your average time on site in the old model would be 3 minutes, but in the new model it would be 9 minutes.

September 16, 2011 11:27 AM

Nick Budden said:

Hi Jeremy,

Thank you for the great post, I've been search for something like this for quite some time. I'm running a Wordpress network using subdomain installs, and currently all of my sites are being tracked using a single profile. What I hope to accomplish is to have one profile that tracks my primary domain AND my subdomains, and also to have an individual profile associated with each of my individual subdomains. I have a relatively small number of subdomains, and can customize my code for each if needed (i.e. my wordpress users cannot create their own subdomains...the solution does not need to be very dynamic). What would you suggest as the best solution for this?

Again thank you for the article!

October 5, 2011 3:50 PM

Kamran Jamshidi said:

This has been bookmarked, informative and well explained.

Using: _gaq.push(['_addIgnoredRef', 'example-petstore.com']); to filter own things away is useful.

Same goes with search engine reports etc from analytics, you get more clean data using features like:
_gaq.push(['_addIgnoredOrganic', 'www.mydomainname.com']);

October 10, 2011 6:02 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

While it's possible to track everything with a single account number and create the profiles for individual subdomains using filters, it probably makes the most sense to set up a second tracker for each subdomain with a separate account number. The reason is that there are types of hits that cannot be easily excluded using filters, which would show up in all of your profiles unless you took additional measures. This behavior is not well-defined, so you are best off using separate accounts.

Note, however, that these can simply be sub accounts within your main GA account. The profile for your main site might use UA-12345678-1, while the profiles for your subdomains might use UA-12345678-2, UA-12345678-3, etc. Also, the code for each subdomain should probably have the same subdomain modifications as your global tracking code unless you have specific reasons for not doing so. This can help to avoid subtle issues like having global tracking code that includes a leading period on your main site along with tracking code just for the main site that has no subdomain modifications, but in fact includes subdomain tracking that does not use the leading period by default, resulting in a hash conflict.

October 11, 2011 8:04 AM

justin brock said:

Great article, Jeremy.

Google recently updated the subdomain tracking video on Conversion University. In it they advise the leading period. http://services.google.com/analytics/breeze/en/domains_subdomains/index.html

Is your advice still not to use the leading period for those of us who only have subdomains, as opposed to lower-level subdomains?

October 13, 2011 12:20 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Justin: Yes, I still prefer to not use the leading period in situations where there are no lower-level subdomains. Lower-level subdomains are the only situation where a leading period is required. Not including the leading period tends to result in more forgiving tracking code. If someone manages to put up a page without code or the incorrect code, if they launch a website optimizer test, or if they were previously not previously doing subdomain tracking and update their code to include subdomain tracking modifications--all of these situations are handled much better without the leading period.

October 13, 2011 1:35 PM

Dan Lyons said:

Hi Jeremy,

Here's the issue I'm trying to solve:

I have multiple sites with different product catalogues.

SiteA.com - primary site. All shopping cart conversions happen through here. It has multiple subdomains.

SiteB.com - separate domain with no subdomains, has online store. But when an item is "added to cart" on this site, it sends the visitor to SiteA.com to complete the purchase. There is a unique "added to cart" page on SiteA.com that a visitor only sees if they came from SiteB.com - think of it as SiteA.com/cart/SiteBcart-addedtocart. This means anytime we see a pageview of SiteA.com/cart/SiteBcart-addedtocart in the GA reports, it means they were on SiteB and added something into their cart.

We're collecting all data into one profile - this includes SiteA.com and its subdomains and SiteB.com. Code we're using on SiteA.com and its subdomains is as follows:

var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-123456-1']);
_gaq.push(['_setDomainName', 'sitea.com']);
_gaq.push(['_setAllowHash', false]);
_gaq.push(['_setAllowLinker', true]);
_gaq.push(['_trackPageview']);
_gaq.push(['_trackPageLoadTime']);

SiteB.com code:
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-123456-1']);
_gaq.push(['_setDomainName', 'siteb.com']);
_gaq.push(['_setAllowHash', false]);
_gaq.push(['_setAllowLinker', true]);
_gaq.push(['_trackPageview']);
_gaq.push(['_trackPageLoadTime']);

We've tagged all links sending someone from siteb.com to sitea.com with linkbypost.

The issue: while we're tracking visitors successfully on both domains and subdomains, it seems the cookie is getting dropped when an item is placed in the cart on SiteB.com. When I look in the content report and segment down everyone who saw SiteA.com/cart/SiteBcart-addedtocart (visitors I know could only have come from siteb.com to sitea.com after placing an item in their cart) and then use a secondary dimension to identify their source, I'm seeing them as referrals from SiteB.com. I would also expect their landing page to be somewhere on SiteB.com, but landing page is showing up as SiteA.com/cart/SiteBcart-addedtocart.

Would appreciate your thoughts on why the cookie might be getting dropped in this instance.

Thanks!

October 15, 2011 10:42 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Dan: When you tag the links from one domain to the other, the cookie information from the first domain is passed to the second domain through the query string. Oftentimes with carts, these query parameters can become corrupted or may be stripped from the final URL altogether. You would need to confirm that this isn't happening. If it is, then there may be a way to work around it, but it will likely be rather complicated.

October 17, 2011 8:47 AM

ryan said:

Great article. Now for the code you recommend.... Does that go on both the main url and the subdomain? Thanks. Ryan

November 2, 2011 2:10 PM

Kim K said:

If the link to open the subdomain opens in a new window, will that cause a new session to be started? I have the correct codes on the domain and subdomain, but I see that a cookie is being writtem for the subdomain and it doesn't contain the original referrer data. Want to tell my client that they should open the links to the subdomain in the same window. I have never run across this particular "flavor" of setup, although I have coded up dozens and dozens of cross domain tracking setups.

November 23, 2011 2:47 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Kim: Opening the subdomain in a new window should not affect cookies. If cookies are being written improperly, then that means there is some issue with the Google Analytics Tracking Code on the subdomain. Even if the code on the subdomain is correct, it's possible that Google Website Optimizer code, Google Analytics Tracking Code from another vendor, or 3rd party code with built-in Google Analytics Integration might create a second second set of cookies for the subdomain.

November 28, 2011 9:08 AM

Nate said:

Great Post. Quick question. We are tracking multiple subdomains and top level domains on one tag. I noticed a lot of self referrals and came across this post. But have discovered something else. My issue is with the subdomains. One subdomain did not get updated with the GA tag. It had no tag at all. This subdomain is commonly hit when passing between two other subdomains. With this tag being absent, how bad did we mess up our data over that time? So if the users path was as follows (and it always will be):

subdomainA.domain.com > subdomainB.domain.com > subdomainC.domain.com - what did this do to our data?

Obviously we got a referral from subdomainB when, and lost our correct referral information I assume, and did not get page views on subdomainB, but did we also inflate visit count? Did we get a visit when they landed on A and exit when they landed on B and then a new visit when they landed on C?

I know that's a little off topic of this post, but if you have some insight that would be great.

December 15, 2011 2:45 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Nate: In Google Analytics, a session ends when there has been more than 30 minutes between pageviews. When the session ends, this means that the next pageview will result in a new visit and that the referral information of the visitor is subject to being updated. If it's been less than 30 minutes, however, then the referral information will not update unless it's something other than a site referral (i.e. tagged or organic).

This means that you will only get self-referrals when the visitor has spend more than 30 minutes on subdomainB. This also means that whenever the source changes from something else to a self-referral, a new visit has resulted with a new landing page and the visit count has been inflated.

December 15, 2011 3:38 PM

Saul said:

Hi! Thanks for this useful article. I have a one domain and 2 subdomains with your code implementation. But I don't know how track visitors from one subdomain to another..I mean how many new visitors has come to a subdomain and then went to another subdomain for example.

Sorry for my english.

December 23, 2011 6:15 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Saul: This code is for tracking a domain and its subdomains as a single site. When this is implemented, traffic moving from one subdomain to another is not as visible as it would be with the default code. If it's more important for you to see the subdomains as separate sites, then it may be better to just stick with the default code. There are ways to set up two accounts in Google Analytics and track subdomains both ways, as separate sites and as a single site, but this can be tricky to get right. The main concern is that cookies will likely be shared on the main domain unless you make sure to always resolve to www and the account that tracks subdomains individually explicitly sets the domain name to the FQDN (e.g. _gaq.push(['t2._setDomainName', 'www.domain.com']); or _gaq.push(['t2._setDomainName', document.domain]);).

December 27, 2011 10:14 AM

Blanka said:

Hi Jeremy,

the article is great, although I still have troubles with setting the subdomains tracking. We have a big media site with multiple subdomains, but just one parent domain. After customizing the tracking code we got rid of self referrals, but we noticed a huge drop in pageviews, which just doesnt make sense to me. Is there any explanation of why that happens? The code was the following:

_gaq.push(['_setAccount', 'UA-XXXXXXX-1']);
_gaq.push(['_setDomainName', 'mydomain.com']);
_gaq.push(['_trackPageview']);

Thank you!

January 2, 2012 7:31 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Blanka: There shouldn't be a drop in pageviews, so that suggests a configuration issue. One possibility is that the _setDomainName code may be incompatible with some of the subdomains. For example, you might have mydomain.co.uk, or mydomain.someotherdomain.com. Also, if you have multiple levels of subdomains, such as sub1.sub2.mydomain.com, then you'll need to use .mydomain.com instead of mydomain.com. These types of situations all result in no pageviews being generated for the affected subdomain.

January 3, 2012 11:27 AM

Jens said:

Hi Jeremy,

Several days ago I submitted a comment. Since thena couple of other comments have been published, but not mine. Is there a chance my comment ended up in the spam list? I would be really interested to get your feedback on a couple of my questions...

Thanks, Jens

January 3, 2012 7:23 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Jens: I searched for your other comment, but I wasn't able to find it (not even in the spam list). If you wouldn't mind reposting your questions, I would be happy to answer them.

January 4, 2012 8:22 AM

AB said:

This is a very useful post.

A couple of questions:

We were previously using setdomain without a period before the domain name. When we adjusted the GA code for subdomain tracking we then ADDED a period inadvertently.

We noticed that both direct traffic and goal completions increased tremendously.

Is this because users were likely dually cookied and goal completions fired twice?

Thanks,

February 1, 2012 12:41 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@AB: I'm not sure why goal completions would go up, but switching from non-leading period to leading period causes a cookie reset, which results in an increase in direct traffic. Leading period and non-leading period cookies are completely incompatible; each destroys the other.

February 6, 2012 2:55 PM

AB said:

Paid traffic is also showing as direct. Would adding the leading period resolve this issue?

Thanks,

February 7, 2012 10:37 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@AB: Consistency is key. In most cases, it doesn't really matter whether or not you use the leading period, but it does matter that you do the same exact thing on every page of the site. If you have some pages with the leading period and some without, that will seriously affect tracking. Also, any other GA based script on the site needs to be consistent as well. For example, if you're running a GWO test on the site, the same modifications need to be made there as well, including urchin.js style modifications (i.e. _udn = ".example.com";). Sometimes third party scripts will include their own GA tracking, which typically needs to be disabled to avoid interfering with your own code.

Paid Traffic showing up as direct could also be a result of redirects stripping the tags or landing pages with missing or incorrect GA code. For AdWords, you also need to make sure that autotagging is enabled, that your Adwords and Analytics accounts are linked, and that cost data has been applied to all relevant profiles.

February 7, 2012 10:53 AM

Abhijeet Kotwal said:

Hi,

I have a website and a blog which I'm tracking using GA.

We are using following accounts to track the site and the blog (sub domain)

For the main website example.com: UA-1234567-1

For the blog.example.com: UA-1234567-2

The problem is currently, I have to see two separate GA reports and Google is treating Traffic separately.

What I need is, the traffic to the website and blog should be considered as a single source of traffic and
single Report where I can monitor Source, Audience, Content, etc.

P.S. The Website is hosted separately and blog is on WordPress.

Please suggest a solution.

Thanks
Abhijeet

February 9, 2012 4:05 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Abhijeet: You should change the code on the blog so that it uses UA-1234567-1 instead of UA-1234567-2. You'll also need to modify the code on both the blog and the main site for subdomain tracking. Usually this means adding a line of code immediately after the _gaq.push(['_setAccount', 'UA-1234567-1']); line that looks like this:

_gaq.push(['_setDomainName', 'example.com']);

The code may be different depending on the version of GA you have up on the site. If you're using a WordPress plugin for GA, there should be an option to specify the domain as "example.com". I believe it's called "Domain Tracking" under advanced settings.

February 9, 2012 8:48 AM

TW said:

First of all, thank you for this amazingly useful article. Good info is tough to find on this subdomain tracking topic.

My question: I am currently developing a new site (brand new) that will have upwards of 15 subdomains. Since a lot of your advice here deals with those who had previous (no leading period) setups, would you still recommend the no-leading-period setup to me even though I am starting new?

I'm simply trying to figure the best way to track all 15 subdomains in one profile while still able to differentiate between the subdomains in traffic reports.

Any advice is greatly appreciated - thanks!

February 9, 2012 11:56 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@TW: I still prefer no leading period for new setups as long as there aren't multiple levels of subdomains because it gives you a more forgiving setup. For example, a person may set up a Google Website Optimizer test on the site and forget to modify the code for subdomains. If you use the leading period, visitors who get entered into the test will likely have their cookies thoroughly thrashed, leading to invalid data in GA. If your site doesn't use the leading period, then while the GWO setup is not ideal, you have a greater chance of keeping your GA data intact. Similarly, if someone sets up another page or subdomain and forgets to add subdomain modifications to the tracking code, you're more likely to be OK if the rest of your site does not use the leading period than if it does.

As far as differentiating between subdomains in the traffic reports, you can do this for the most part using advanced filters. Advanced filters can let you see all the visits that touched a particular subdomain. It will also include pageviews from other subdomains if they were part of that visit.

If you need to distinguish between subdomains at the pageview level, then I would use an advanced filter to add a prefix to request uri indicating the subdomain. For example, you can set it up so that blog.example.com/index.html will show up in the reports as /blog/index.html. This can be done with a single advanced filter, or with multiple filters if you have longer subdomains that you want to shorten in the page-level reports.

February 9, 2012 12:25 PM

TW said:

Jeremy: Many thanks!

So, to make sure I understand your advice 100%, you're saying:

1) Set up tracking code on all 15 subdomains the same way:

//Tracking code customizations only
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-12345-1']);
_gaq.push(['_setDomainName', 'example-petstore.com']);
_gaq.push(['_addIgnoredRef', 'example-petstore.com']);
_gaq.push(['_trackPageview']);

2) Distinguish between subdomains at the pageview level through advanced filtering / custom reports

If you feel like giving me additional insight into the best way to set up that advanced filter, I'm all ears.

Thanks again!

February 9, 2012 3:55 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@TW: 1. Yes. 2. Advanced Segmentation and standard filters on the profile. The following is one way to set up the filters:

http://code.google.com/apis/analytics/docs/tracking/gaTrackingSite.html#profilesKey

February 10, 2012 8:28 AM

TW said:

Again: Many thanks!

February 10, 2012 2:50 PM

Abhijeet Kotwal said:

Hi,

Thank you very much for the help!

After your feedback I implemented the following code:

var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-1234567-1']);
_gaq.push(['_setDomainName', 'mydomain.com']);
_gaq.push(['_trackPageview']);
_gaq.push(['_setAllowAnchor', true]);

(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);
})();


I implemented this code for mydomain.com and blog.mydomain.com (both hosted seperately)

But after this code implementation the Bounce Rate has drastically jumped from 20%+ to 60%+... For most of the pages on mydomain.com existing pages.

Could you please tell me how do I fix this issue?


Thanks,
Abhijeet

February 13, 2012 11:33 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Abhijeet: Make sure you include _gaq.push(['_addIgnoredRef', 'mydomain.com']); as well. That's not likely the cause of the bounce rate increase, but it's worth adding regardless. It sounds like there may be some rogue code on the site that's no longer compatible with your main tracking code. You can use a tool like httpfox and see if more than one __utm.gif hit is being generated per page. If that doesn't turn anything up, check your browser reports and see if the bounce rate is affecting only one browser. If it's an IE issue, there are IE specific tools you can use to view hits and cookies to try to determine what's going on. If nothing else, it may be worth rolling back the code temporarily until you can determine what's going wrong in a test environment.

February 14, 2012 8:22 AM

Domenico said:

Hi Jeremy,

thanks for this great article.

I have got an issue: I have got an existing main domain (say example.com) which has been collecting data for a couple of years and I now need to set up a third level domain (say something.example.com) within the same UA. I've followed your instructions as far as the third level domain is concerned so the code looks like

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

and set up a brand new profile under Google Analytics with a filter as "Include only traffic from the domains that are equal to something.example.com"

I have modified the tracking on the main domain site as follows

_gaq.push(['_setAccount', 'UA-XXXX-Y']);
_gaq.push(['_setDomainName', 'example.com']);
_gaq.push(['_addIgnoredRef', 'example.com']);
if(condition == true)
{
_gaq.push(['_setCustomVar', 1, 'CustomVarName', CustomVarValue, 2]); // I need this for some special situations
}
_gaq.push(['_trackPageview']);

but the main domain tracking has immediately dropped to 0, while on the second profile has not been collected at all.

What have I done wrong?

Thanks,
Domenico

March 14, 2012 10:53 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Domenico: I don't see anything wrong with the code you've set up. The behavior sounds like there may be an issue with the domain string you're passing to _setDomainName. If this string does not match the root level domain, then your tracking won't work at all. This could be a typo, or perhaps using .net instead of .com or something along those lines. Also note that while with _addIgnoredRef you could pass just 'example' instead of 'example.com' without any ill-effects, the same is not true of _setDomainName.

As far as the filter is concerned, I generally don't trust any of the pre-built filters, but always use a custom filter with the correct regex. In this case, I'd use a custom include filter on the hostname field with a value of "^something\.example\.com$".

March 14, 2012 11:47 AM

Domenico said:

Unfortunately there was no typo and everything seemed correctly set up, at least to me.

I'll give it another try and hope..

Anyway, thanks for your help.
Domenico

March 14, 2012 1:33 PM

Matt said:

Jeremy,

Great post and seriously impressive that you've responded to every commenter! So here's another one: after implementing this code a few months ago I've reduced the amount of self referrers by about 97% BUT I'm still seeing enough to believe that something still needs to be tweaked. First question, can you every totally eliminate self referrers? Second, based on this code do you see any obvious problems or have any suggestions:

I have a www.domain.com and info.domain.com. Code is the same on both:


try { var pageTracker = _gat._getTracker("UA-1234567-1");
pageTracker._setDomainName("domain.com");
pageTracker._trackPageview();
var supplementalTracker = _gat._getTracker('UA-1234567-2'); supplementalTracker._trackPageview();
} catch (err) { }


notice that I'm also pushing data into a second profile as per a client's request. Finally I didn't use addIgnoredRef and if you think that's the solution please let me know.

Thanks

March 30, 2012 11:59 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Matt: I would use _setDomainName("domain.com") for supplementalTracker as well and use _addIgnoredRef("domain.com") for both. That should take care of any lingering self-referral issues.

I think it's possible, but very difficult, to eliminate all self-referrals. If there are a few lingering self-referrals that make up less than 1% of your overall traffic, especially if also less than 1% of key visits (e.g. converting visits), then it's probably not worth chasing down the remaining fraction of a percent. For complex sites, the bar may be higher than 1%.

March 30, 2012 1:01 PM

Matt said:

Thanks Jeremy! Can you provide some reasons why it may be impossible to remove all self-referrals. The only reason I can think of is old cookies from pre-cross domain tracking modification Visitors.

March 30, 2012 2:15 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Matt: That's one reason. Other reasons include cached pages or pages with old/rogue code.

March 30, 2012 3:22 PM

Maggie said:

Hi Jeremy,

Using your article, we recently updated our GA tracking code to the following:
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-111111-1']);
_gaq.push(['_setDomainName', '.domain.com']);
_gaq.push(['_addIgnoredRef', 'domain.com']);
_gaq.push(['_trackPageview']);

Now we need to implement cross-domain tracking as well. Should we just add the _gaq.push(['_setAllowLinker', true]); line, or we should remove the _addIgnoredRef?

April 5, 2012 7:29 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Maggie: Just add the _gaq.push(['_setAllowLinker', true]); line.

April 5, 2012 8:07 AM

Newbie said:

Hi Jeremy,

Thanks for the great article, it's quite a puzzle getting your head around all these settings to be honest. I'm currently reviewing a proposed implementation (below) which requires the referral data between subdomains to be captured in a separate account for each subdomain and the cross domain data to be captured in one overall account. Do you see any reason why this wouldn't work?


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



_gaq.push(['._setAccount', 'UA-xxxxxxx-1']);
_gaq.push(['._setDomainName', '.domain.com']);
_gaq.push(['._trackPageview']);

April 23, 2012 11:39 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

In order for this work, your main domain must resolve all requests to www.domain.com. If it can resolve/does resolve to just domain.com instead, then you will have cookie conflicts for those pages.

I would also recommend using the following instead:

var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-xxxxxxx-1']);
_gaq.push(['_setDomainName', document.domain]);
_gaq.push(['_trackPageview']);



_gaq.push(['._setAccount', 'UA-xxxxxxx-1']);
_gaq.push(['._setDomainName', '.domain.com']);
_gaq.push(['._trackPageview']);

Passing document.domain set cookies to fully qualified domain name without turning off cookie hashing. Passing 'none' also sets cookies to the fully qualified domain name, but it turns off hashing too. The hash allows the the code to determine the correct set of cookies to read from. When it's turned off, the code will read the first set of cookies it finds, which may be the wrong set.

Also, if you don't have any lower-level subdomains (e.g. my.sub.domain.com), and don't expect to have any, then you should use 'domain.com' instead of '.domain.com' This will make your code a bit more resilient if, say, someone puts some rogue code on the site or launches a Google Website Optimizer test.

April 23, 2012 12:19 PM

Jackye said:

Hi Jeremy..
It's so hard to make that works.
We have 2 sub-domains here, and when I put:

_gaq.push(['_setDomainName', '.example-petstore.com']);
_gaq.push(['_setAllowHash', false]);

It get a lot of self referrals. =/
But I didn't understand your suggestion quite sure..
So How can i do it?
Something like that:

_gaq.push(['_setDomainName', 'domain.com']);
_gaq.push(['_addIgnoredRef', 'domain.com']);
_gaq.push(['_trackPageview']);


What will happen with sub1.domain.com and sub2.domain.com? Should I put the same code? Or do I need to put a change on them too?

Thank you so much, these settings are so hard to understand =/

April 26, 2012 4:09 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Jackye: Yes, the code you posted should work:

_gaq.push(['_setDomainName', 'domain.com']);
_gaq.push(['_addIgnoredRef', 'domain.com']);
_gaq.push(['_trackPageview']);

You would use this same code on both sub1.domain.com and sub2.domain.com.

April 26, 2012 4:55 PM

Jackye said:

Thanks!

Another quick one:

Is there any really difference between this:

_gaq.push(['_setDomainName', '.domain.com']);
_gaq.push(['_addIgnoredRef', '.domain.com']);
_gaq.push(['_trackPageview']);

and this:

_gaq.push(['_setDomainName', 'domain.com']);
_gaq.push(['_addIgnoredRef', 'domain.com']);
_gaq.push(['_trackPageview']);

the "." before domain.com really matters?
our domain here is www.domain.com with subdomains: sub1.domain.com and sub2.domain.com

Thanks again!

April 27, 2012 8:51 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Jackye: Yes, there is a difference. If you use the leading period (the "." before domain.com), then your cookies will be set in such a way that they'll be accessible to lower level subdomains (e.g. lowersub1.sub1.domain.com). Most people do not have lower level subdomains, so this is usually unnecessary. Furthermore, cookies set without the leading period are more compatible with cookies set without any subdomain at all.

So if you have the option to not use the leading period, this is usually the way to go as it makes your code more resilient. For example, someone might launch a Google Website Optimizer test on the page without adding subdomain code, or you might use a 3rd party plugin that also happens to have Google Analytics tracking enable. With these types of situations, there's a greater chance that your tracking will be just fine if you don't use the leading period. Otherwise, both of these scenarios would result in a cookie conflict, with the end result being that your cookies would be destroyed and recreated with incorrect referral information.

For _addIgnoredRef, you should not use the leading period regardless of whether or not you use the leading period for _setDomainName. _addIgnoredRef does a straightforward string comparison between the current domain and the string you pass to it. So if someone can get to, say, domain.com without the www, then _addIgnoredRef won't catch it if it has the leading period. You can, in fact, simplify _addIgnored ref and just pass "domain" if you felt like it. Of course, this would potentially ignore domain.org or domain.net as well, but it's really just to illustrate the fact that _addIgnoredRef just checks to see if the string passed to it is a substring of the current domain.

April 27, 2012 9:35 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Jackye: Yes, there is a difference. If you use the leading period (the "." before domain.com), then your cookies will be set in such a way that they'll be accessible to lower level subdomains (e.g. lowersub1.sub1.domain.com). Most people do not have lower level subdomains, so this is usually unnecessary. Furthermore, cookies set without the leading period are more compatible with cookies set without any subdomain at all.

So if you have the option to not use the leading period, this is usually the way to go as it makes your code more resilient. For example, someone might launch a Google Website Optimizer test on the page without adding subdomain code, or you might use a 3rd party plugin that also happens to have Google Analytics tracking enable. With these types of situations, there's a greater chance that your tracking will be just fine if you don't use the leading period. Otherwise, both of these scenarios would result in a cookie conflict, with the end result being that your cookies would be destroyed and recreated with incorrect referral information.

For _addIgnoredRef, you should not use the leading period regardless of whether or not you use the leading period for _setDomainName. _addIgnoredRef does a straightforward string comparison between the current domain and the string you pass to it. So if someone can get to, say, domain.com without the www, then _addIgnoredRef won't catch it if it has the leading period. You can, in fact, simplify _addIgnored ref and just pass "domain" if you felt like it. Of course, this would potentially ignore domain.org or domain.net as well, but it's really just to illustrate the fact that _addIgnoredRef just checks to see if the string passed to it is a substring of the current domain.

April 27, 2012 9:35 AM

Rita said:

I'm trying to understand this (eek) and set up my GA. I have a .com site such as: www.bookstore.com and on that same domain have added www.bookstore.com/blog. (wordpress) What I don't understand is; is the blog considered the subdomain? And would I put the .com site as the domain and leave the blog as the subdomain? Or would I put the .com/blog and leave the main .com as the subdomain ? Then, what exact code would I add to the generated code so that it would all track properly ? Thanks for keeping it simple. :)

June 1, 2012 12:44 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Rita: What you have is a subdirectory. There's no special code needed in order to track your subdirectory in addition to your main site. The standard GA code should work fine.

If your wordpress blog was on blog.bookstore.com, instead of www.bookstore.com/blog, then you would have a subdomain and would need to modify your code.

June 1, 2012 1:21 PM

Rita said:

@Jeremy, okay my website is a eg. www.bookstore.com and my blog is www.bookstore.com/blog so you said that would make it a subdirectory and no need to update the code. Good. So, my question is; what do I put in the profile settings URL and the property settings URL would I only ever need to put eg; www.bookstore.com and then the .com/blog part would automatically pick up in the stats ? So, should property and profile URL's match ? That is what I need to know to finish signing up with my proper settings. Thanks so much!

June 3, 2012 1:22 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

GA does not consider a subdirectory to be a separate site, even if the hosting for that subdirectory is different for the rest of your site. It will pick up on your subdirectory automatically. If you decide to create a profile that only reports on your blog subdirectory, you will need to add a filter to that new profile to only include traffic to that subdirectory. The profile name should probably include the subdirectory as well, only to be able to distinguish it from your main profile, but the subdirectory does not need to be included as part of the URL, and you should not create a new web property for the subdirectory, but rather use the existing web property for your main site.

June 4, 2012 8:50 AM

Nathan Arthur said:

Hello, Jeremy!

I've got a question for you: Will subdomain tracking work when the main domain and the subdomain use different versions of the GA tracking code? I'm using an eCommerce service (store.mydomain.com) which uses legacy ga tracking code, whereas my main site (mydomain.com) uses the new asynchronous version.

The problem I'm trying to fix is that any traffic that came from my main site, to the store, and then ended in a purchase, shows as direct traffic. The original referral data isn't being preserved.

My modified code looks like this:

mydomain.com/.org code:

var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-xxxxxxx-y']);
_gaq.push(['_setDomainName', 'mydomain.com']);
_gaq.push(['_addIgnoredRef', 'mydomain.com']);
_gaq.push(['_addIgnoredRef', 'mydomain.org']);
_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);
})();

store.mydomain.com code:

var pageTracker = _gat._getTracker('UA-xxxxxxx-y');
pageTracker._addDevId('o5cUG');
pageTracker._setAllowLinker(true);
pageTracker._setDomainName('none');
try{pageTracker._setDomainName('mydomain.com');
pageTracker._addIgnoredRef('mydomain.com');
pageTracker._addIgnoredRef('mydomain.org');}catch(e){};
pageTracker._trackPageview();

What am I doing wrong?

June 14, 2012 2:21 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Nathan: You can use different versions of the GA tracking code on different pages. The issue you're having is that visitors are going from a .org site to a .com site. This is a cross-domain situation, which means that you'll need to modify your code for cross domain tracking:

https://developers.google.com/analytics/devguides/collection/gajs/gaTrackingSite

More specifically, you should not have both _setDomainName('none') and _setDomainName('mydomain.com'). I would use the latter on both mydomain.com and store.mydomain.com, and use _setDomainName('mydomain.org') on mydomain.org. You should also include _setAllowLinker('true') on all three sites and make sure to use _link or _linkByPost as appropriate on any links or forms that go from .org to .com or vice versa.

June 15, 2012 8:30 AM

Nathan Arthur said:

Thank you so much for the reply!

So .org is just an alias of our .com address. Anything available on the .com is available on the .org. Is there a way to make Google Analytics play nice with this, and not have to worry about tracking then like they were two different sites? Would using only "_setDomainName('mydomain.com');" achieve that?

I would really like to avoid having to worry about cross-domain tracking if at all possible. We've even thrown around the idea of just setting up a site-wide 301 redirect from .org to .com if it would take the cross-domain aspect out of the picture. I'd rather not have to resort to that, though.

June 18, 2012 8:59 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Nathan: 301 redirecting from .org to .com would avoid the cross-domain situation. Alternatively, you could also have a store.mydomain.org in addition to store.mydomain.com. Then you would just need to be consistent with your links and maintain separate tracking codes for the .org and .com sites, since the _setDomainName line would be different for the .org and the .com sites.

There are also scripts which can be used to tag all of the links going between the two domains. It's still considered cross-domain, but it can take some of the pain out of the setup. It's also not too hard to write your own script, especially if you already have a JavaScript library like jQuery on the site. The trickest part is getting such scripts to work for edge cases such as links and forms with multiple redirects and things like that. If you have full control over all sites, then you may be able to eliminate those types of situations if any exist, which can greatly simplify cross-domain tracking.

June 19, 2012 8:06 AM

Stuti said:

Thank you so much for this.
Made my day
God bless you :)

July 30, 2012 1:55 PM

vincent said:

hi Jeremy:

i have also encounted the self-referral issue, and should it add the the modify code "_gaq.push(['_addIgnoredRef', 'sister-site.com']);" to all pages in each subdomain? or add only one statement in the front page

November 2, 2012 11:16 PM

vincent said:

hi jeremy

i also have the self-referral issue, and i followed your instrcution adding the modified code :"_gaq.push(['_addIgnoredRef', 'sister-site.com']);"
in each pages of our maindomain. but the problem still exist.

should i add the modified code for each pages under each subdomain? or just add only a statement on the front page of our main domain?

as u menetioned in our article :"This also eliminates the need to add a separate _addIgnoredRef statement for each subdomain."

so confused..

November 3, 2012 12:00 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@vincent: You should add the same modification to all subdomains as well.

There is a common misconception that you need to add a separate _addIgnoredRef statement for each subdomain:

// BAD EXAMPLE
_gaq.push(['_addIgnoredRef', 'www.sister-site.com']);
_gaq.push(['_addIgnoredRef', 'blog.sister-site.com']);
_gaq.push(['_addIgnoredRef', 'shop.sister-site.com']);

Instead, only one line is necessary site-wide, regardless of how many subdomains you have:

// GOOD EXAMPLE
_gaq.push(['_addIgnoredRef', 'sister-site.com']);

Note also that the official documentation still recommends:

// BAD EXAMPLE
_gaq.push(['_addIgnoredRef', 'www.sister-site.com']);

which is still wrong since it won't match requests for your domain without the 'www', nor for subdomains.

November 5, 2012 7:55 AM

Jasmina said:

Hello

I want to track www.example.com and not other subdomains, e.g. static.example.com. To that effect I've tried setting _gaq.push(['_setDomainName', 'www.example.com']); but this is not working out as the cookie is still set to example.com so it's also set for static.example.com

How would you recommend that this is implemented so that the cookie is only set for www.example.com and not for static.example.com or any other subdomain?

301 redirect is in place for example.com to www.example.com

November 7, 2012 6:23 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Jasmina: The line you're adding should work, so if you're having trouble with it, make sure you're adding it after the _setAccount line but before the _trackPageview line.

November 8, 2012 7:51 AM

Jasmina said:

Ta Jeremy, it became obvious as soon as I read your comment.

November 8, 2012 4:27 PM

Poulpator said:

Hi,
I have more than 200 subdomain.
And a need to know each unique visitor per subdomain.
Is there a way to view data per subdomain without creating a profile for each subdomain?

Regards from French Alps

November 20, 2012 11:36 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Poulpator: You can set up a custom report with Hostname as a dimension and unique visitors as a metric.

November 20, 2012 3:29 PM

Chris Eldredge said:

are any recommendations in this article now out of date?

thanks for the great article!

May 21, 2013 4:34 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

The code modifications recommended by this article for subdomain tracking are still up to date for ga.js.

May 22, 2013 8:09 AM

Pavel said:

Jeremy, sorry if this has already been answered before, but I couldn't find it in the 3 years of comments to this topic, so would appreciate if you could help me out.
We have a website with 3 language versions.
www.website.com for english
lang1.website.com for lang 1
lang2.website.com for lang 2

Currently we have a default tracking code installed which results in inflated visits, recorded under Referral section of google analytics.

Do we understand this correctly that adding
_gaq.push(['_addIgnoredRef', 'website.com']);
would eliminate those self-referrals?

So if originally the user came from Google to a www-version and then switched to lang1., then with the updated tracking code, Google Analytics would report that visit as a single visit originating from Google but would include two Domain Names under this visit which were visited by the user.

Hmmm, but then, that would be two visits, no?

Do you know, how would such a visit be reflected in the GA-report?

December 6, 2013 12:03 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Pavel: Assuming you're still using ga.js analytics, you will need both lines:

_gaq.push(['_setDomainName', 'website.com']);
_gaq.push(['_addIgnoredRef', 'website.com']);

December 9, 2013 12:42 PM

anna-lisa said:

Hi Jeremy, thanks for your helpful post. I have a question: I have a cross domain & subdomain issue, site A with subdomain A1/A2/A3 and so on, and the conversion/transaction occurs on Site B. I have set a duplicated complete profile for all visits to site A with a filter which includes all visits coming from subdomains. Then I have set single profiles for each subdomain with a filter including visits from each subdomain (filter Host name). On these single profiles I can't see any conversion/transaction. I presume it's because the filter includes only visits from subdomain, so visits (and conversions) from Site B are excluded.

Am I right? Is there a way to solve this problem?

February 28, 2014 5:38 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

If you track all of the domains and sub domains in a single view/profile, then you should be able to create custom advanced segments for each subdomain. Any filter solution would likely require a complicated set of 3 filters based on an indicator on Site B that lets you know which sub domain it's currently being used for.

March 3, 2014 9:04 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

If you track all of the domains and sub domains in a single view/profile, then you should be able to create custom advanced segments for each subdomain. Any filter solution would likely require a complicated set of 3 filters based on an indicator on Site B that lets you know which sub domain it's currently being used for.

March 3, 2014 9:04 AM

Damion said:

Brilliant! I just wish this post was written..... er, the last time I needed to have this as a reference! I had to cobble together a fix from those various inadequate, outdated, fuzzy articles you mention.

I've bookmarked this, and hopefully I'll remember its existence next time the sound of dying tracking is all around. Devs all too often give little thought to how tracking might be affected by their "quirky" subdomain (or even multi-domain) structure, and I'm hoping that this article might be able to solve a few problems before they spiral out of control. Thanks once again!

January 5, 2011 5:13 PM

Eric Polatty said:

If you go to the tracking code section under profile settings in your GA account, and click "one domain with multiple subodmains" under "what are you tracking", I notice the code Google generates for you to use does not include the _setAllowHash tag. But they tell you to include it in the Google Code article for subdomain tracking. I understand it's a free product - but I find Google's inability to make up their minds about how to use their own software frustrating to say the least.

January 6, 2011 9:51 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Eric: My guess is that the Google Code example includes _setAllowHash because it is on a page dedicated to cross-domain tracking. Unfortunately there's currently no Google Code page that just deals with subdomain tracking. I think we lost this during the transition from the traditional ga.js code to the async code, but I'm hopeful that this will be addressed.

The code that's generated from your Google Analytics account is better, but still suffers from the other issues I went over. The lack of an _addIgnoredRef line, or rather the lack of the logic behind the _addIgnoredRef line being executed for an appropriate _setDomainName call, is especially disconcerting since it implies that _setDomainName is sufficient for optimum subdomain tracking.

January 6, 2011 10:37 AM

Eric Polatty said:

@Jeremy - Most of the main Google Code article is on cross-domain situations, but there is a section "tracking across a domain and it's sudomains" and it has the _setAllowHash tag there.

January 7, 2011 10:26 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Eric: It's possible that since it was sandwiched between the other cross-domain examples that the _setAllowHash tag was added unintentionally. Regardless, it shouldn't be there for a subdomain only example.

January 7, 2011 10:32 AM

Mike Sullivan said:

Thank you! Thank you! Thank you!

We added (yet another) subdomain to our environment over the holidays and I tried (yet again) to get rid of the self-referrals. There's so much not-quite-right guidance out there!

Made your suggested changes and today, they have dropped WAY off!

January 7, 2011 11:50 AM

Adam said:

Great article. I'd just about given up on solving the self referrals issue.

Question: if your site uses both subdomains and lower level subdomains, should you use a leading period on both, or just your lower level subdomain pages?

January 7, 2011 12:05 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Adam: If your site has lower level subdomains, then you should use the leading period site-wide.

If you used the leading period on some subdomains and not on others, the hash codes for the cookies would be different, so your cookies would get destroyed every time you crossed from a page using the leading period to a page not using the leading period and vice versa. So regardless of whether you decide/need to use the leading period or not, you want to be consistent.

January 7, 2011 2:09 PM

david said:

Hi Jeremy,

This article of yours was definitely a nice reading.

I experienced myself lots of issues a few weeks ago when adding subdomain tracking to our site, following Google instructions. One of the main problems was a huge boost of direct traffic (we were using leading period, but we didnt use SetAllowHash).

I am willing to try your solution now. However, would you still recommend this implementation (no period and AddIgnoreRef) even for the traditional ga.js code?

January 10, 2011 7:20 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@David: Yes, I would recommend this solution even if you're using the traditional ga.js code. This would look something like the following:

var pageTracker = _gat._getTracker("UA-12345-1");
pageTracker._setDomainName("example-petstore.com");
pageTracker._addIgnoredRef("example-petstore.com");
pageTracker._trackPageview();

A sudden influx of direct traffic can result from going from no subdomain tracking to subdomain tracking with the leading period. Removing the leading period may help, but this depends on how long you've had the code with the leading period up. There aren't any hard or fast rules on this, but I would say that if you've only had the code with the leading period up for a month or more, you might be better off sticking with it at this point.

There's nothing inherently wrong with using the leading period. The main issue I have with it is that for a site that the hash code generated when you use the leading period is different than the one generated when you don't have subdomain tracking at all. If you've already been using the leading period for a significant amount of time, then switching your code to not use the leading period may be just as bad for tracking as switching to using the leading period in the first place.

Also, for a brand new Google Analytics installation, using the leading period is perfectly fine.

January 10, 2011 8:02 AM

David said:

Thanks for your advice, Jeremy. I will keep your considerations in mind and try your proposed subdomain tracking code.

We had the code with the leading period for just a couple of days. The breakage of the data was big enough to get quickly back to the older version, even though it was not taking into account the existing subdomains.

Hopefully I will get a chance to try your suggestions some day next week. Our site has a large amount of traffic, so after a few hours we will be ready to say if it is working or not. I will let you know ;)

January 10, 2011 10:19 AM

Cloga said:

Excellence article!Thank you!

January 10, 2011 10:46 AM

Cristina Chetroi said:

Hi Jeremy!
The _addIgnoredRef tip to minimise self-referrals is great, as they really are a pain. Thanks!

I also remember someone mentioning the inconsistency between the code GA console generates for subdomain tracking (no setAllowHash to false) and the official documentation.

We all wish domain hashing needn't be compromised. But the reality is that it often is - it's common that a client decides to introduce subdomains or other domains at a later stage and you need to tweak the snippet as the result.

So, when it happens, would it be possible to introduce some sort of cookie checkup for returning visitors and do some sort of merge instead of setting a second set cookies/destroying them?

January 12, 2011 5:19 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Cristina: It would certainly be possible to do that. I've done something similar to that before with cookies that were generated with _setNamespace, so it shouldn't be that hard. I have some other ideas about how this might be done as well, something I'm hoping to write about in a future post.

January 13, 2011 7:54 AM

Liz said:

would i use this customization on all subdomains and the top level domains? Or just all the subdomains I want to track - I will have about 4 or 5 of them.

Thanks

January 27, 2011 2:27 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Liz: I would recommend using the modification on all subdomains and top level domains. I have seen some cases where people wanted to track certain subdomains only so they could see traffic coming from other subdomains as referrals, but this is not an ideal setup. Inevitably someone also wants to track the other subdomains, which gives you strange mix of referrals from subdomains and original referral data to those subdomains showing up in your reports. Instead, you should track everything and use filters in Google Analytics to exclude the unwanted domains.

January 27, 2011 4:26 PM

Bernd said:

You wrote:
_gaq.push(['_setDomainName', 'example-petstore.com']);

Google says:
_gaq.push(['_setDomainName', '.example-petstore.com']);

(see the dot before domainname).

What is the difference?

January 30, 2011 2:16 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Bernd: The main differences are that:

1. Each generates a different hash, but not including a leading period has the same hash as no subdomain tracking at all.
2. Including a leading period works for sites with lower level subdomains (ex. buy.store.example-petstore.com).

Google includes the leading period to account for #2. The reason I don't include the leading period is because of #1. It feel that it's more likely that someone is transitioning their code from no subdomain tracking to subdomain tracking than that they have lower level subdomains.

So, as mentioned in the article, if you have lower level subdomains, or if you're setting up Google Analytics Tracking Code on your site for the first time, use the leading period. If you don't have lower level subdomains and you've had Google Analytics Tracking Code on your site for a while, then don't use the leading period.

January 31, 2011 7:54 AM

Bernd said:

OK, thank you very much, Jeremy!

January 31, 2011 1:33 PM

Nick said:

I'm a little confused. Your second point says that you have to use the leading period if you have lower level subdomains, but then at the end you said don't use if you don't have to.

Let's say I have example.com and store.example.com, would I want to use the leading period to track this properly?

January 31, 2011 5:52 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Nick: The only time you have to use the leading period is if you have lower level subdomains. For your example, the leading period is unnecessary for tracking this properly because you don't have any lower level subdomains. You'd have to have another level of subdomain tacked on to there, such as buy.store.example.com.

If you don't have lower level subdomains and you're setting up Google Analytics for the first time on a site, then you have the option to either use or not use the leading period. I tend to not use it as this tends to be more stable, again because the hash code is the same as if you didn't have subdomain tracking on the main domain. So if someone else sets up a Google Website Optimizer test on your homepage, for example, and forgets to add subdomain tracking modifications, this isn't as big of a deal if you had implemented subdomain tracking without the leading period.

The main benefit to using the leading period for new sites without lower level subdomains is that you'll have less people question your setup since it's closer to the Google recommendations.

For sites with existing Google Analytics Tracking Code that you want to update to use subdomain tracking code, not using the leading period will lead to a much smoother transition. Of course, if your site also has lower level subdomain, you'll have to bite the bullet and use the leading period anyway.

Whichever way you decide to go, make sure that you apply that decision consistently across your site. Having some pages that use the leading period and some that don't will wreak havoc on your site.

February 1, 2011 7:56 AM

Chris said:

I'm working on a WordPress MultiSite project which uses subdomain, some of which are mapped to other domains. So what I'm doing really is more in line with the Google example since its not just sub-domain tracking but cross-domain tracking. My question to you is is there any benefit to using _addIgnoredRef for cross-domain tracking? Or could it hurt in any way? I'm looking to reduce self referals as much as possible.

February 4, 2011 12:21 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Chris: Using _addIgnoredRef will still help some with preventing self-referrals. You should have one _addIgnoredRef statement for each root level domain. _addIgnoredRef only ignores a referral if there is previous referral data to fall back on.

So if you have any links between domains that aren't tagged with the proper linking parameters, this will show up in your reports as self-referrals, even if you use _addIgnoredRef. This is a good thing, because it provides visibility for fixable self-referrals.

If there is previous referral data, however, _addIgnoredRef will preserve it. This can be especially useful in situations where you can tag links to a third-party domain, but have trouble tagging links going back to the original domain.

February 4, 2011 8:33 AM

Rob said:

I tried using Google's subdomain tracking suggestion to no avail. For 1 day I did see in GA URL's from the subdomain but I have not been able to figure out how. I came upon this blog after discussing this with a GA expert who has been gracious enough to help us try a few options.

So I adjusted the subdomain code to look like this, per your suggestions:

var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-xxxxxxx-y']);
_gaq.push(['_setDomainName', 'cae-nyc.org']);
_gaq.push(['_addIgnoredRef', 'cae-nyc.org']);
_gaq.push(['_trackPageview']);


The primary/main Drupal-driven domain has this:


var _gaq = _gaq || [];
_gaq.push(["_setAccount", "UA-xxxxxxx-y"]);
_gaq.push(['_setDomainName', 'cae-nyc.org']);
_gaq.push(['_addIgnoredRef', 'cae-nyc.org']);
_gaq.push(["_trackPageview"]);

Now, a thing to note: we have 2 URL's that we use, hosted on a share GoDaddy account: caenyc.org and cae-nyc.org. (Notice a hyphen). The subdomain does NOT have a hyphen it' all advocacy.caenyc.org. I do not have access to an Apache httpd.conf file so I have to use GoDaddy's GUI/Total Domain Control to create the redirect. Could that be causing the problem? Can you peak at both domains & view their source?

Thanks!

Rob

February 8, 2011 9:44 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Rob: Your code should be different depending on which domain it's on. So on cae-nyc.org (with the hyphen), your code should look like the following:

var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-xxxxxxx-y']);
_gaq.push(['_setDomainName', 'cae-nyc.org']);
_gaq.push(['_addIgnoredRef', 'cae-nyc.org']);
_gaq.push(['_trackPageview']);

But on caenyc.org (without the hyphen), your code should look like the following:

var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-xxxxxxx-y']);
_gaq.push(['_setDomainName', 'caenyc.org']);
_gaq.push(['_addIgnoredRef', 'caenyc.org']);
_gaq.push(['_trackPageview']);

The value you pass to _setDomainName must match the domain it's on, otherwise the code will fail. This is also true when you're tracking both example.com and example.net.

I also don't know if visitors can go back and forth between cae-nyc.org and caenyc.org. If they can, then that falls under the realm of cross-domain tracking, which requires a completely different set of tracking code modifications. Still, you'll need to fix the _setDomainName line on caenyc.org to get any kind of tracking there at all.

February 8, 2011 1:03 PM

Rob said:

Sigh, I wish I had tried the obvious yep that worked. And yes people can go from the sub-domain to the main domain and vice verse.

So for example, an email campaign might start with the sub-domain. Then a person fills out the form on the sub-domain, and clicks on Home, which goes back to the main www domain.

Or, people will click on a link from www, e.g., on the home page, and go to the sub-domain, fill out the form, and may hit home. Does that mean cross-domain?

Also, using the sub-domain filter, the Content report is showing the paths with a leading / like this:

/advocacy.caenyc.org/site/apps/kb/cs/contactsearch.asp

or

/advocacy.caenyc.org/site/c.rwL4JlO7KzE/b.6421085/k.DF6F/Petition_to_Incoming_Schools_Chancellor_Cathie_Black/apps/ka/ct/contactus.asp?c=rwL4JlO7KzE&b=6421085&en=ftINKXMILiKPJ5PUJeILI3OLInKZI7OKJgIXK6OQKtK9F


I take it I can transform the URL with another filter?

February 8, 2011 4:53 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Rob: You only need to implement cross-domain tracking if a visitor can move across root level domains. Going from avocacy.caenyc.org to www.caenyc.org does not count as cross-domain because you're just moving from one subdomain of caenyc.org to another.

Going from avocacy.caenyc.org to www.cae-nyc.org, however, does count as cross-domain tracking and requires additional modifications to your code, as well as modifications to the links going between domains. Generally it's something to be avoided if at all possible.

In your situation, the easiest way to avoid the issue is to just 301 redirect visitors who request cae-nyc.org pages to the appropriate caenyc.org page. This eliminates the need for cross-domain tracking and dramatically simplifies your Google Analytics setup.

With regard to filters, yes, you can apply additional filters after the subdomain filter. Those filters will be applied to the modified URL instead of the original URL, so you can use this to change the URL to look exactly how you want it to in Google Analytics. Also, you may want to look at Exclude URL Query Parameters under the Main Website Profile Information to remove any unnecessary query parameters and clean up reporting even further. This is usually easier than using filters to remove the query parameters.

February 9, 2011 7:57 AM

Emily said:

I have multiple domains that I have the same UA# (cookmedical.com, cookbiodesign.com and cookartlab.com). These domains feed traffic between each other and so it would be helpful if I could track them as if they were all the same site to track users between the domains. Based on this information it sounds like I should add the following to all of the pages in all the domains:

_gaq.push(['_setDomainName', 'none']);
_gaq.push(['_addIgnoredRef', 'cookmedical.com']);
_gaq.push(['_addIgnoredRef', 'cookbiodesign.com']);
_gaq.push(['_addIgnoredRef', 'cookartlab.com']);

Am I understanding you correctly?

February 9, 2011 8:48 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Emily: The _addIgnoredRef lines may help with some self-referrals issues, but they're not directly related to cross-domain tracking.

Cross-domain tracking in Google Analytics is the sort of thing that really deserves a series of posts, but I'll try to summarize it as best as I can within this comment.

First, I generally avoid using _gaq.push(['_setDomainName', 'none']); because it does too much. _gaq.push(['_setAllowHash', false]); (no quotes around false) accomplishes the minimum for cross-domain tracking, so it's preferred.

Second, you'll also need to add _gaq.push(['_setAllowLinker', true]); (again, no quotes around true).

Third, you'll need to modify the links between domains. The easiest way to do this is to have the following onclick attribute in the link:

onclick="_gaq.push(['_link', this.href]); return false;"

This covers most scenarios, but not all of them. There will likely be additional nuances that these instructions won't handle. The official Google Code article may help with some of these.

Here are some other things to keep in mind:

1. _link invokes a javascript redirect, which means the referrer won't be available on the receiving page in IE. There are other ways to do this that preserve the referrer, but they are more advanced.
2. _linkByPost may work with forms that use GET instead of POST, but you'll have to specifiy true in the third parameter, that is:

_gaq.push(['_linkByPost', this, true]);

This passes query parameters through the anchor text instead of the query string. This means you'll also need to add _gaq.push(['_setAllowAnchor', true]); to your Google Analytics Tracking Code.
3. It's generally preferred to accomplish linking between domains in a more dynamic way. You might be able to build this into a template driven site, or use a script that modifies onclick attributes of links dynamically.
4. You should try to minimize redirects between domains. These will often do unintended things to query parameters and anchor text and make cross-domain tracking very difficult or impossible.

Because of all the complications involved in cross-domain tracking, you may want to consider purchasing a support plan to ensure that everything is set up correctly.

February 9, 2011 9:18 AM

Emily said:

Thanks that helps a lot. I talked to my developer about this and we're building a dynamic script to add the onClick function to the links that are moving between domains that we want to track together.
I agree that it would be best if we didn't have this highly related content on different domains and we are in the process of redesigning our overall site to include the pages that are currently on separate domains. In the mean time we really need to be able to see how users are moving through our sites.

Thank you for all your help!

February 9, 2011 10:44 AM

Eduardo Cereto said:

The argument that the leading dot can cause problems when you're changing a GA implementation is valid. But what's not clear in the post is your opinion about new implementations.

Since a new implementation doesn't have any already set cookie we should bother, than I think there's no drawback about using the leading dot.

I always use the leading dot in my new implementation, and will keep doing so.

I'm not only worried about the sub-sub-domains. But the leading dot feels more compliant with the RFC that specifies that the absence of it can cause Rejection of the cookie. I'm not sure how many browsers acctually comply to that statements, none I know of. Still I'd rather not take my chances.

http://www.ietf.org/rfc/rfc2109.txt

Quoting the RFC:
4.3.2 Rejecting Cookies
...
* The value for the Domain attribute contains no embedded dots or
does not start with a dot.

[page] 4
Domain=domain
Optional. The Domain attribute specifies the domain for which the
cookie is valid. An explicitly specified domain must always start
with a dot.

February 10, 2011 10:32 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Eduardo: I think that you can argue it either way for new Google Analytics implementations. I prefer not to use the leading period even for leading implementations (assuming of course that there aren't any sub-sub-domains). The reason is that this type of setup tends to be more forgiving when it comes to things such as rogue Google Website Optimizer tests where someone forgot to add subdomain tracking modifications.

If the RFC were an issue, then it seems like Google would have addressed this in the standard Google Analytics Tracking Code. As stands right now, if you don't do any subdomain tracking at all, then the cookies are set without the leading period. So this leads me to believe that it's a non-issue at least as far as cookie compliance is concerned.

Either way you approach this, you're going to have exceptions:

1. If you default to using the leading period, then anytime you add subdomain tracking on a site that already had Google Analytics implemented, then you'll have to consider how much of a negative impact using the leading period is going to have and possibly not use it.
2. If you default to not using the leading period, then anytime you add subdomain tracking you'll have to make sure/hope there aren't any sub-sub-domains.

For me, I find that the exceptions for #2 crop up far less frequently than for #1. Not only that, handling the exceptions for #2 is pretty cut and dry, whereas handling those for #1 involve much more of a judgment call.

Also, to be perfectly honest, I've always felt more comfortable not using the leading period. It's always felt like the right way to do it. It seems to lead to safer setups. But I can easily see how someone could have started out always using the leading period and so instead they feel more comfortable using, it feels right, it seems safer. So I'm OK with someone taking the #1 approach to it instead, but I'll probably continue taking the #2 approach.

February 10, 2011 12:49 PM

Steffen said:

Hey Jeremy, thanks for your post. Very interesting.

I'm facing the following problem: with a few days gap after deploying your recommended tracking setting, traffic from a referring subdomain drops significantly. Expected effect on _addIgnoredRef(). Meanwhile, direct traffic increases. That - in turn - is not what I expected and in my case not supposed to be. What's the benefit from tracking subdomain traffic as direct traffic? That's even more confusing than tracking as referring. I expected that traffic to become "internal" traffic. How to achieve that?
And why is that gap from ... say 10 days?

Thanks in advance.

February 24, 2011 7:56 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Steffen: I can't determine the exact cause without seeing the code or looking at the site, but if traffic from a subdomain is showing up as direct, then that indicates some type of code inconsistency between the main domain and the subdomain. Here are some things to consider:

1. Are you wanting to track the main domain and the subdomain together? Sometimes people want to track these separately, or they don't want to/can't track the subdomain for some reason and want it tracked as a referring source. This article assumes that you do want to track them together.

2. If you're tracking the main domain and the subdomain together, then the Google Analytics Tracking Code on each should be very similar, if not identical. In particular, the _setDomainName and _setAllowHash statements (or lack thereof) must be identical. You can't have a leading period on one and not on the other, use _setDomainName("none") on one and not on the other, or use _setAllowHash("false") on one and not on the other.

3. Are you running any Google Website Optimizer tests on either the main domain or the subdomain? Similar to #2, the Google Website Optimizer code must have the same set of modifications as your Google Analytics Tracking Code. This is fairly straightforward for the tracking script and conversion script, but the control script needs to be modified using equivalent urchin.js style modifications.

4. Is there any other Google Analytics Tracking Code on any of the pages? This includes legacy code, code put there by someone else for some other purpose, or even UTM code for Urchin. Any extra code like this will need to either be modified to match your Google Analytics Tracking Code or removed.

February 24, 2011 8:20 AM

Cory said:

Hi Jeremy,

This is such a great article. I recently spent a lot of time scratching my head over some self-referrals until we saw this.

I quickly implemented your code as outlined above on a simple (/path/page.aspx) www domain and a developer added matching script on a more complex transaction subdomain(pages.aspx?pid=000 etc)

Unfortunately, I'm able to see only traffic that moves from the "complex" (www) site to the "simple" (subdomain) site but not the other way around.

What do you think that means? On which CMS should I look to edit?

Thank you!

February 24, 2011 1:08 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Cory: My previous comment most likely applies here as well. In particular, you should check both sites for legacy Google Analytics Tracking Code that might have a different set of modifications than the code you just added. The legacy code will then have to either be modified or removed.

February 24, 2011 1:20 PM

Peter O'Neill said:

Hi Jeremy,

Just had a long discussion with an ex-colleague about _addignoredref and want to clarify what the impact of it is.

In point 3 of the blog, you recommend using it to avoid self-referrals when a visit session expires between pageviews. That makes sense but I can't see this causing a high percentage of self-referrals. For most sites, this should occur a minimal number of times. If a site has many visits timing out (maybe due to video), would suggest increasing length of visit.

Instead won't using this code eliminate recording of all self referrals as they will all be reported as the previous referrers or as Direct? As you say in one of the comments, this information can be useful for finding untagged pages or untagged links between subdomains.

Thanks - Peter

March 4, 2011 6:25 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Peter: Pages with a lot of content or videos can certainly exacerbate the issue, but self-referrals will often make up 1 to 2 % or more of traffic even on sites without videos or long sales letters.

I'll speculate on why and say that in general, we often don't have a captive audience on the web. Someone may be on one site, think of something and open up a tab to check something on another site, or maybe they notice they have an email, or maybe they get a phone call, etc. Depending on the type site, they may also be doing comparison shopping and have 10 different tabs open at once.

Regardless of why this is happening, _addIgnoredRef is a nice solution because it only applies to visitors that have previous referral data available. This means that a visitor won't just show up as direct instead of a self-referral, unless of course they were previously direct.

A new visitor who starts at an untagged page and moves to a tagged page will still show up a a self-referral, even if you're using _addIgnoredRef. Eventually this will happen for enough visitors that you'll see the problem in your Google Analytics reports.

This is especially true of untagged landing pages, but a page not designed to be a landing page will usually still end up as a landing page for enough people to point out the problem in Google Analytics. But if you still have the 1 to 2% of noise coming from self-referrals that could have easily been prevented by _addIgnoredRef, it makes it much harder to catch these pages.

Even if self-referrals only showed up for true problems, I'd still use _addIgnoredRef because it's more important to preserve referral information when possible than to fix a problem on a single page. If the page is important enough, then the tagging issue on that page will become obvious at some point anyway, even without a bunch of self-referrals to point it out. If it's not a very important page, then the misfortune of having that page missing from your reports is still outweighed by the benefit of having correct referral information for those visitors who spent a little too long on that page (or the previous page) for whatever reason.

March 4, 2011 7:57 AM

Peter O'Neill said:

Thanks for the detailed reply. I hadn't realised the degree to which self-referrals are driven by visitors timing out - that does change the situation.

I also agree with your logic on using _addIgnoredRef based on how you have described it as working. However that appears to be different to the Google description (which I know is wrong occasionally). They say

Excludes a source as a referring site. Use this option when you want to set certain referring links as direct traffic, rather than as referring sites. For example, your company might own another domain that you want to track as direct traffic so that it does not show up on the "Referring Sites" reports.

This suggests that all traffic from the domain specified will be reported as Direct. As opposed to what you have written which is it will pick up the previous referrer for returning visitors and have no affect on new visitors. Have you found that this is the way it works in practice and that this is another example of where Google needs to update their documentation?

March 4, 2011 12:49 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Peter: Yes, I would say that the Google documentation on _addIgnoredRef is a bit misleading. In practice, it works as I've described it.

March 4, 2011 1:07 PM

Peter O'Neill said:

Ok, that explains my confusion. Thanks for the assistance and the detailed explanations given.

March 4, 2011 1:26 PM

Rene said:

Very useful information and i did understand it until you mentioned crossdomain tracking needing a different approach with:
_gaq.push(['_setAllowHash', false]);
_gaq.push(['_setAllowLinker', true]);

What if you want to track example.com, store.example.com and example2.com together.So this would be Tracking Across Multiple Domains and one Sub-domain.

Would you use the following?

example.com
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-12345-1']);
_gaq.push(['_setDomainName', 'example.com']);
_gaq.push(['_setAllowHash', false]);
_gaq.push(['_setAllowLinker', true]);
_gaq.push(['_addIgnoredRef', 'example.com']);
_gaq.push(['_addIgnoredRef', 'example2.com']);
_gaq.push(['_trackPageview']);

store.example.com
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-12345-1']);
_gaq.push(['_setDomainName', 'example.com']);
_gaq.push(['_setAllowHash', false]);
_gaq.push(['_setAllowLinker', true]);
_gaq.push(['_addIgnoredRef', 'example.com']);
_gaq.push(['_addIgnoredRef', 'example2.com']);
_gaq.push(['_trackPageview']);

example2.com
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-12345-1']);
_gaq.push(['_setDomainName', 'example.com']);
_gaq.push(['_setAllowHash', false]);
_gaq.push(['_setAllowLinker', true]);
_gaq.push(['_addIgnoredRef', 'example.com']);
_gaq.push(['_addIgnoredRef', 'example2.com']);
_gaq.push(['_trackPageview']);

March 15, 2011 5:31 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Rene: The code for example2.com should be a little different:

var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-12345-1']);
_gaq.push(['_setDomainName', 'example2.com']);
_gaq.push(['_setAllowHash', false]);
_gaq.push(['_setAllowLinker', true]);
_gaq.push(['_addIgnoredRef', 'example.com']);
_gaq.push(['_addIgnoredRef', 'example2.com']);
_gaq.push(['_trackPageview']);

It'd important that the _setDomainName call match the root level domain of the site the code is on. If it doesn't match, then no cookies will be set and you won't get any Google Analytics data for those pages.

March 15, 2011 7:51 AM

Jeff said:

What if I want to track all of my subdomains independently? How do I set that up?
Each of my clients will have a branded website for themselves that I am hosting as a subdomain. I need to be able to generate a report showing Client A his traffic without any other clients info in there.
Currently we only have about 8-10 of these clients but the number is growing and could reach into the hundreds.
Any suggestions for this GA challenged guy?
Thanks in advance!
Jeff

March 28, 2011 4:19 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Jeff: See the comment at the end of the this post.

March 28, 2011 5:03 PM

Jeff said:

Thank you! I didn't realize there was a different post and kept looking at this one for a reply.
Thank you again!

March 30, 2011 12:59 AM

anobre said:

Hi there!
I've implemented this tracking code style and it seems to be working great with a catch. Now when i go , for instance, to top content report and click 'visit link' i'am always sent to the top domain when in most cases i should be redirected to a subdomain.

Cheers,

April 14, 2011 3:11 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@anobre: You'll need to add two steps to this:

1. Add a filter to add the hostname to the beginning of the request uri. Usually I use something like this:

Filter type: Custom Filter (Advanced)
Field A: Hostname
Extract A: (.*)
Field B: Request URI
Extract B: (.*)
Output to: Request URI
Constructor: $A1$B1
Field A Required: Yes
Field B Required: Yes
Override Output Field: Yes

2. Edit the Main Website Profile Information and change the Website URL to:

http://

This won't fix the existing data in your profile, but going forward, clicking on a link will go to the correct subdomain. This works for sites with multiple domains as well.

April 14, 2011 3:44 PM

Ryan said:

Hi Jeremy - great post. I was trying to follow along your comment discussion with Rene about cross-domain with sub-domain tracking but believe I missed something.

If I am tracking from www.mainstore.com (or mainstore.com) to 3rd party checkout which is a sub subdomain: checkout.sub.main.net - is what I have correct:


Site (mainstore.com):
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-XXXXX']);
_gaq.push(['_setDomainName', '.mainstore.com']);
_gaq.push(['_setAllowHash', false]);
_gaq.push(['_setAllowLinker', true]);
_gaq.push(['_setAllowAnchor', true]);
_gaq.push(['_addIgnoredRef', 'mainstore.com']);
_gaq.push(['_trackPageview']);


3rd Party (checkout.sub.main.net):

var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-XXXXX']);
_gaq.push(['_setDomainName', '.main.net']);
_gaq.push(['_setAllowHash', false]);
_gaq.push(['_setAllowLinker', true]);
_gaq.push(['_setAllowAnchor', true]);
_gaq.push(['_addIgnoredRef', 'mainstore.com']);
_gaq.push(['_addIgnoredRef', 'main.net']);
_gaq.push(['_trackPageview']);


Does that look correct (assuming the linker tags are in place)?

April 14, 2011 4:30 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Ryan: That code looks fine. The one thing I would add is that the _setDomainName call is optional for the third party domain unless you're tracking across subdomains on the third party domain. That is, if a visitor goes from your site to checkout.sub.main.net and doesn't see any other subdomains on main.net, then there's no need to do subdomain tracking for the third party domain.

Also, if you have two sites, one with sub subdomains and the other without sub subdomains, technically you only have to use the leading period on the site with sub sub domains. So even if a visitor could go from checkout.sub.main.next to somewhere else on main.net, that doesn't mean you need a leading period for mainstore.com as well.

As discussed in the article, you can certainly still include the leading period if you feel strongly about it, but there are benefits to not using the leading period which you might be able to take advantage of. It might also be difficult to remember which sites you have to use it for and which you don't, in which case always using the leading period may make more sense.

April 14, 2011 4:52 PM

Ryan said:

Great, I will try taking out the leading periods. Thank you Jeremy

April 14, 2011 4:55 PM

Brian Moore ? said:

Some thing tells me I ruined/fubar'd my analytics.

ok I have a ecommerce site using a 3rd party shopping cart.

my analytics code is this:
mysite.com

var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-*********-1']);
_gaq.push(['_setDomainName', 'none']);
_gaq.push(['_setAllowLinker', true]);
_gaq.push(['_setAllowHash', false]);

3rd party cart
cart.com

var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-********-1']);
_gaq.push(['_setDomainName', 'none']);
_gaq.push(['_setAllowLinker', true]);
_gaq.push(['_trackPageview', 'insert_page_name']);


ever since i implemented this code change so my boss could get the google adwords conversion tracking working the main site shows up as a referrer and now the ecommerce conversion rate in google analytics has droped to zero.

help please.

April 19, 2011 1:35 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Brian: I don't see a _trackPageview call for the mysite.com analytics call, but you may have just left that off. It's also not necessary to have both _gaq.push(['_setDomainName', 'none']); and _gaq.push(['_setAllowHash', false]); on the mysite.com code. You should probably drop the _setDomainName call.

My best guess is that you probably had some sort of linking in place that is now broken as a result of updating your code to the async version. Without knowing anything else, the easiest way you can probably fix that is to add the following after your Google Analytics Tracking Code:

_gaq.push(function() {
window.pageTracker = _gat._getTrackerByName();
});

You can add this after both your mysite.com code and your 3rd party code, assuming that the 3rd party domain links back to your main domain correctly.

April 19, 2011 2:45 PM

Ryan said:

Hi Jeremy,

Unfortunately I am still getting mostly (direct) transactions in my reporting. About 1/3 do contain the referring keyword so I believe I must be on the right track but am perhaps missing something.

This is with a Yahoo! store and I believe I have to the two links tagged correctly that point to the cross-domain from sunshineyoga.com to checkout:(yahoo.net).

Can I pay you to review at my implementation (via view source) to make sure I have the cross links tagged?

When I run through in WASP it looks like the cookie retains all the data so I'm not quite sure what the issue is.

Thank you!

April 20, 2011 11:01 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Ryan: We no longer offer stand-alone Google Analytics support plans. You should look into using Monitus in order to track Yahoo Store. That is what we always recommend for tracking Yahoo Store.

April 20, 2011 12:20 PM

Ryan said:

Do you have anyone you can refer me to?

Not really interested in having to pay monthly for GA data.

Thanks!

April 20, 2011 2:37 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Ryan: Monitus is the only viable solution for tracking Yahoo Stores. So if you don't want to pay monthly, you'll probably want to look into using something besides the Yahoo Store.

April 20, 2011 3:01 PM

Dan said:

If my sub domains have no reference or relationship to the TLD, would I not get valid results if I treated the sub domain the same as a TLD?
I setup a site in a WP multi site environment so wouldn't I just treat the sub domain the same as a TLD, generate and implement analytics the same way I would for a TLD?
Dan

May 2, 2011 10:34 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Dan: If the subdomain does not refer to the main domain and vice versa, then you do not need to implement subdomain tracking. The standard Google Analytics Tracking Code will work fine for both sites. You can either use separate account numbers (within the same Google Analytics account) to track each domain separately, or use the same one if you want roll-up reporting.

The same goes for multiple domains as well. If you have multiple domains and no domain links to any of the other domains, then there's no need to implement cross-domain tracking. The standard Google Analytics Tracking Code will work fine for all sites. And again, you can track the sites separately or in a roll-up profile (or both).

May 4, 2011 8:03 AM

Eric W said:

Hi Jeremy - great article. I recently added similar code in an attempt to fix self-referrals for our websites. The result was partially successful, they dropped dramatically for April (implemented 3/31).

However, we also experienced a massive unexplained drop in Visits and UV's, while our PV and every other performance metric increased.

Is there any reason that getting rid of self-referrals would lower UV's (or, to phrase properly, improperly having self referrals would have been inflating UV counts?)

Thanks,
Eric

May 9, 2011 9:20 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Eric: Self referrals will usually result in inflated visit counts. Inflated UV counts are less common, but this is also possible depending on what your code looked like before. Unique visitor counts are largely based on the __utma cookie remaining intact. So if your Google Analytics Tracking Code setup results in this cookie being recreated, then you will get an artificial spike in UVs.

May 10, 2011 7:59 AM

Eric W said:

Thank you very much! I was able remove my fix and test it and actually see the Unique Visitor ID change, creating extra UV's. Appreciate your feedback!

May 10, 2011 11:06 AM

Eric said:

Another question for you Jeremy.

Our sites have 1 main domain and 1 main subdomain. We get a ton of self referrals and corrected some of them by adding 1 missing line of code to our main domain pages.

However, we are still getting quite a few.

Here is the code we are using. Is this correct?


var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA of Main Page']);
_gaq.push(['_setDomainName', '.ericsite.com']); (this line was missing and was added 5 weeks ago, fixing about 60% of our self referrals)
_gaq.push(['_trackPageview']);

_gaq.push(['_setAccount', 'UA of rollup account']);
_gaq.push(['_setDomainName', '.ericsite.com']);
_gaq.push(['_trackPageview']);
_gaq.push(['_setAccount', 'UA of another rollup account']);
_gaq.push(['_setDomainName', '.ericsite.com']);
_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);
})();

May 12, 2011 4:30 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Eric: As mentioned in the post you should also add the following line for each account:

_gaq.push(['_addIgnoredRef', 'ericsite.com']);

This line can go right after the _setDomainName line for each account. Also note that I intentionally left out the period in front of ericsite.com. This is correct regardless of whether you use a leading period with _setDomainName or not.

May 12, 2011 4:45 PM

Eric said:

Thanks again, will report back results!

May 12, 2011 9:14 PM

Eric said:

Greetings again -

The addition of that code has had no impact. If we had our sites live for a solid 6 months with a subdomain issue, is it possible/likely that the remaining self-referrals we still see after fixing things are simply "baked" in to cookies and not fixable until the cookie expires?

Very much at a loss now.

Thanks again!
Eric

May 23, 2011 7:46 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Eric: Yes, it may take some time to work itself out. Not only do you have return visitors who already have cookies for self-referrals, but you also potentially have return visitors who are viewing cached pages with the old code that may still have their referral information overwritten with a self-referral.

Also note that this code change doesn't address other fixable sources of self-referral traffic. For example, if you have a landing page that's missing the tracking code altogether, the code change won't fix those self-referrals, but you can still fix the issue by adding the tracking code to that landing page.

May 24, 2011 7:13 AM

Eric said:

Couple more things.

#1 - I've had one site that has been fixed for 3 months now (2/22 fix date). That being the case, I'd expect their remaining self-referrals to be slowly dropping off over time. However, they are staying pretty flat since the initial drop from my 2/22 fix. That concerns me.

#2 - I added the hash setting to the site I tried your suggestion on last week. It now looks like this :
var _gaq = _gaq || [];
_gaq.push(['_setAccount', '']);
_gaq.push(['_setDomainName', '.ericsite.com']);
_gaq.push(['_addIgnoredRef', 'ericsite.com']);
_gaq.push(['_setAllowHash', false]);
_gaq.push(['_trackPageview']);


While the addition of addIgnoredRef last week had no impact on the self-referral count, the addition of setAllowHash false seems to have had a definite impact in lessening the self-referrals.

Does that make any sense to you?

Are there any drawbacks to turning off the hash like that?

Thanks again!
Eric

May 25, 2011 2:02 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Eric: Turning the hash off would cause a cookie reset for all your return visitors. So while this does remove all of the lingering self-referrals, it also removes all of the referral attribution for all of your return visitors. Most likely you're now seeing a jump in direct traffic.

May 26, 2011 7:37 AM

Eric said:

Yep - that's exactly what happening. Direct jumped from 32% to 49%.

Is the cookie reset from turning off hash a 1 time thing?

In other words, if I leave it as is, are the cookies being constantly reset for the same user over and over?

Thank you sooo much for the assistance. Invaluable.

May 26, 2011 1:48 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Eric: The cookies will only be reset a maximum of once per user, and only for users visited the site prior to the code change. For new visitors, the cookies will be set correctly for the first visit and will not be reset for subsequent visits (though of course standard attribution rules apply).

May 26, 2011 3:16 PM

Jonathan said:

Hi Jeremy - fantastic post, I've been looking for a way to fix our self-referral issue for a very long time.

Before I implement the changes you suggest (i.e. add addIgnoredRef) , a quick question about leading periods:

We've been using Google Analytics across multiple subdomains (but no lower level domains) for over a year, and have always used setDomainName with a leading period. I know you generally recommend not to use the leading period when making the "switch" to subdomain tracking, but what would you do in our situation, given that we've already used the leading period in setDomainName for such a long time?

Thanks for your help!
Jonathan

June 1, 2011 12:58 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Jonathan: If you've been using the leading period the whole time, then you're probably better off sticking with it. The main exception would if you've often had cookie corruption due to things like poor Google Website Optimizer implementations. In that case, moving to not using the leading period would still cause an initial cookie reset, but might prevent additional cookie resets down the road.

June 1, 2011 5:31 PM

Doug Gebhardt said:

What an amazing post. Thanks so much Jeremy. Looks like it has kept you hopping! I'm wondering about what happens when www2 is showing up in my referral traffic as the number 1 referrer. Would this help to eliminate this sort of self referral? Here is what we have right now.
var pageTracker = _gat._getTracker("UA-1234567-1");
pageTracker._setDomainName(".sample.ca");
pageTracker._setAllowLinker(true);
pageTracker._setAllowHash(false);
pageTracker._trackPageview();
Based on your other answers here, the leading period should be removed in the setDomainName as well to prevent the subdomains as showing up as referrers.
Cheers!

June 5, 2011 9:44 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Doug: The main reason for leaving off the leading period is that it creates cookies that are compatible with the standard, unmodified Google Analytics Tracking Code on your main domain. If you're using the leading period and already have for a while, then switching will cause a cookie reset. Also, whether or not you use the leading period does not affect whether or not you have self-referrals.

Adding the following line should help with some of the self-referrals:

pageTracker._addIgnoredRef("sample.ca");

As mentioned in the post, the leading period should not be used for this method, regardless of whether or not you use it in your _setDomainName call. This call can go right after _setDomainName call.

It's always possible that there may be some other reason why you're getting self-referrals, but this addresses one source of self-referrals caused by subdomain tracking in general.

June 6, 2011 7:26 AM

Devendra Singh said:

Quite informative post, especially because it even tries to correct some documentation mistakes of GA.

A small query please:
We have couple of websites on subdomains. Each one does its own SEO to attract Search Engine Traffic. The Visitors may land to any of the subdomain websites from Search Engine Referral. Later if the Visitor clicks a link to move to the sister subdomain, we still see the original source as the Referral Site. That's okay. But, is there a way to track that how many referrals were transferred to each other (without event tracking)?

Thanks,

DS

July 3, 2011 12:19 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Devendra: You could probably do this to some extent with custom variables or internal site search tracking. Another option would be to use a second tracking object. This would look something like this:

_gaq.push(['_setAccount', 'UA-XXXXXXX-1']);
_gaq.push(['_setDomainName', 'mydomain.com']);
_gaq.push(['_trackPageview']);

_gaq.push(['t2._setAccount', 'UA-XXXXXXX-2']);
_gaq.push(['t2._setDomainName', document.domain]);
_gaq.push(['t2._trackPageview']);

The idea here is that the first tracking object will have its cookies set to the root level domain, while the second tracking object will have its cookies set to the entire domain, including the subdomain. Some key things to notice:

1. Two separate accounts are used (UA-XXXXXXX-1 and UA-XXXXXXX-2).
2. 'mydomain.com' is a string while document.domain is not
3. This will only work reliably well in single domain with subdomain situations.
4. For the same reason as #3, do not use _gaq.push(['_setAllowHash', false]); even if you see documentation that says that you need to for subdomains.

July 5, 2011 7:45 AM

Ruby said:

Hi Jeremy, thanks for writing the article. It is very useful. I am new to GA. I have few questions about subdomain tracking.

I have a website site with sub.example.com and subsub.sub.example.com. The subsub.sub.example.com is not a brand new site so I should use

_gaq.push(['_setDomainName', '.example.com']);

to allow leading time for the site. With the dot in front of the domain name. Is it correct?

The code below should be in both sub.example.com and subsub.sub.example.com sites:

var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-12345-1']);
_gaq.push(['_setDomainName', '.example.com']);
_gaq.push(['_addIgnoredRef', 'example.com']);
_gaq.push(['_trackPageview']);

Also there is another subdomains under the same domain name, for example abc.example.com and efg.example .com. Will the code above track traffic from the other sub domains as well?

Many thanks

July 13, 2011 9:40 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Ruby: Your code looks correct. Because you have multiple levels of subdomains (e.g. subsub.sub.example.com), the leading period is strictly necessary. The same code works for just one level of subdomains (e.g. abc.example.com). The addIgnoredRef call is also correct; no leading period gives you the best coverage since this is simply a substring match using indexOf.

July 14, 2011 10:52 AM

webzdev said:

Hello Jeremy thnak you very much for your post. It was like hell for me to clarify to myself what is right and what is wrong.

I have following situation:
A year ago I did set up GA on a domain example.com BUT code looks like this:
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-xxxxxx-y']);
_gaq.push(['_setDomainName', '.example.com']);
_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);
})();

now I created a subdomain sub.example.com created a separate Profile in GA dashboard. Now I have 2 profiles for site url example.com. I copied GA code suggested by google, pasted it on sub.** but code looks like tihs:
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-xxxxxx-y']);
_gaq.push(['_setDomainName', '.example.com']);
_gaq.push(['_trackPageview']);
(it is the same as this on my main domain) I notice in dashboard there are different profile IDs but they are not addressed in the GA code.

I am confused what exactly should I do to track my subdomain AS A FULLY INDEPENDENT site.
Should I add sub.example.com as new site so I receive a different code or should I retain the second profile with some adjustments??

July 24, 2011 12:25 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

When you add a new profile, you should select the option to add the profile for a new domain rather than an existing domain. This will give you an account number that's separate from your existing profile. Note, however, that the only difference between the two account numbers will be the "-y" at the very end of the number. This is sufficient to track the sites separately.

Also, since you're tracking this subdomain separately, you may want to consider removing the _setDomainName line, to avoid sharing cookies between this subdomain and your existing site.

July 25, 2011 9:16 AM

Vikas Sahdev ? said:

Hi Jeremy,
You are the recognized GA expert here, so I would ask your advice. In between reading multiple threads, I am sort of confused and want to clarify whether what I am doing is correct.

I have two sites: www.example.com and a subdomain www.blog.example.com

What I want is:

1. Sub domain tracking

2. One GA Profile which tracks both the main domain and sub domain.

3. Conversion funnel from all pages on the www.blog.example.com to www.example.com

This is what I have done so far:


1.
I added the below code to www.example.com and www.blog.example.com:

var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-XXXXXX-1']);
_gaq.push(['_setDomainName', 'example.com']);
_gaq.push(['_addIgnoredRef', 'example.com']);
_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);
})();

2.

Created one Master Profile in GA( for www.example.com) without any filters


3.

Created a duplicate of the Master Profile in GA( for www.example.com) with the subdomain filter described earlier in the thread.


Below are the Questions I have:

1. Does the above set up look correct considering what I want to achieve?
2. It has been a day since I set up the second profile but still don't see any visits. Any ideas if something is wrong?
3. I want to implement a funnel whereby i want to track how many visitors from anywhere on www.blog.example.com came to www.example.com. Both the sites don't have default pages in the url( i.e no www.blog.example.com/default.aspx e.g). So in the funnel, how do i define step1 and step 2 urls since both sites have "/" as their default page?

4. Since both the profiles I have contain data from both sites, how do I "filter" reports for one site vs the other? For e.g I woudl like to know the unique visitors to only the blog site and not the main domain site. Is that possible?


Thanks a ton for your help looking into this.


July 29, 2011 5:32 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

Your best bet is to probably use an advanced filter for visits that include both hostnames. You could set this up as a goal, but it would only be useful if you checked the required step box, and even then only within the Funnel Visualization report. When you have a filter that modifies the request uri, the Goal URL and Funnel Steps should match the modified request uri instead, which means that you can do a head match on blog.example.com and www.example.com. The main thing to check if there's still no data is that the other profile is a duplicate of the other one, that is, the web properties should be the same. It's easy to create another profile that uses a -2 instead of a -1 in its Google Analytics Tracking Code.

August 1, 2011 5:29 PM

Vikas Sahdev ? said:

Thanks Jeremy. I have two more questions from your original article:

1. _gaq.push(['_addIgnoredRef', 'example.com']);

If I put the above line in the GA code, both for root domain and subdomain, would I still see the traffic coming from www.blog.example.com to www.example.com. Since I would like to track conversion from the blog site(sub domain) to main site( root domain), I don't want to loose the referrals from blog site to main site.

What reports exactly get impacted by using the code line above? Is it only the Reffering sites report?


2. _gaq.push(['_setDomainName', 'example.com']);

We had a separate GA ID for the subdomain and root domain and thus separate profiles in GA for each of those and we were using leading period in the setDomainName. This was happening for over a year.

Recently we started using the same GA ID for the subdomain and root domain and one profile for both sites with the cross domain filter applied.

In this situation, do you recommend that we keep the leading period or remove it in the above line of code ?

I am also confused by your original comment in the article which says "What this means is that if you weren't doing subdomain tracking previously".

I am not sure what exactly constitutes "doing subdomain tracking" to be able to say whether that condition applies to us. What I am doing is summarized in the previous post. Does that constitute what you meant by "doing subdomain tracking"?


Thanks again!!

August 9, 2011 7:01 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Vikas: _addIgnoredRef is a soft ignore, that is, it only ignores the referrer if there is pre-existing referral information. For example, if your tracking code is set up so that someone starting on the blog and moving to the main domain is counted as a blog referral, then adding _addIgnoredRef won't change that. If instead someone starts on the main site, moves to the blog, then moves back to the main site, then they will not count as a blog referral, even if they spent more than 30 minutes on the blog, because there were already cookies on the main site.

If you were previously using the leading period with _setDomainName, it's probably best to continue using the leading period unless you've been having problems. For example, if someone keeps setting up GWO tests and they can't remember to add proper subdomain tracking modifications, dropping the leading period might help alleviate some of those issues.

"Doing subdomain tracking" refers to using _setDomainName to share cookies across subdomains, regardless of whether you used the leading period. If you have subdomains, but you're not using _setDomainName, then you're not doing subdomain tracking because each subdomain is more or less being treated as a separate site.

In your scenario, it sounds like you want to be able to see traffic that's referred from the blog. In that case, using any form of _setDomainName doesn't make sense because you don't want the cookies to be shared between the two subdomains. _addIgnoredRef probably isn't a bad idea though since it will only give the blog credit when they came to the blog first. You won't easily be able to tell which keywords that sent visitors to the blog resulted in conversions on the main site, however, since those conversions will be credited to the blog instead of the keyword.

August 10, 2011 7:34 AM

Darius said:

Hi,

I tried this but it doesn't work. It still double counts visits over sub-domains, but now it just comes through as all direct. (I implemented it on a website which gets no traffic - so it was a controlled test).

The implementation suggested on the GA website also doesn't work. It ends up with loads of self-referrals.

August 11, 2011 5:47 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Darius: It's hard to know what the issue is without seeing the site. Normally with something like this I would use a cookie viewer like firebug with firecookie and a headers viewer like httpfox so I can see exactly when the issue occurs. Usually you can just use some fake tags like http://www.example.com/?utm_source=test&utm_medium=test&utm_campaign=test and then see when the cookies change to direct.

It may be that there's some rogue code on the page that doesn't have proper subdomain modifications that's causing the issue. This code could be legacy code that's still on the page, Google Website Optimizer code, or possible urchin Urchin UTM code.

August 11, 2011 7:53 AM

Tauseef said:

Hi Jeremy,

Thanks for the information. I update the code to track sub domain and domain traffic. I have two top level domain mobile.customizedstickers.com
blog.customizedstickers.com

The one I am more want to see not as a referral traffic is mobile cause I get conversion from that (Paid and Organic). After changing the code Now getting traffic as a direct.

Any idea why it's doing it or just a old cookies kicking in.

Any help will be highly appreciable.

Thanks in advance.

Tauseef

August 11, 2011 5:16 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Tauseef: Most likely the direct traffic is return traffic to the site. Because both of your domains are subdomains, the cookies by default would have been at the subdomain level. Now that you've implemented subdomain tracking, cookies will be read and created at the root level domain. This means that you may lose information for returning visitors. Over time, this number should decrease and the percentage of direct traffic should go down.

August 12, 2011 9:43 AM

Owen Smith said:

Hi Jeremy,

Perhaps you can help me out with an issue I'm having.

I have a website like so: mysubdomain.x.x.ca

I store static content (css, js, etc) at: static.mysubdomain.x.x.ca

Now, I don't want cookies to get set on the static subdomain for caching purposes.

On my pages, my tracker looks like :
var _gaq=[
['_setAccount',''],
['_setDomainName', 'mysubdomain.x.x.ca'],
['_trackPageview']
];

However the cookies are still set as ".mysubdomain.x.x.ca"

Can you provide any insight on not including lower-level subdomains?

August 14, 2011 2:54 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Owen: If you explicitly need cookies to not be available for any other domains, then you'll need to use something like this:

_gaq=[
['_setAccount',''],
['_setDomainName', 'none'],
['_trackPageview']
];

Then the cookies will only be available to the domain they were set on. Note that this will also affect the hash, so you need to be careful to check that this works as you expect it to. Also, it might be best not to explicitly set _gaq to an array. _gaq is only temporarily an array; it's later rewritten as an object. So it might not always work as expected.

August 15, 2011 8:05 AM

Ken Holden said:

Would this work for issues regarding a secure subdomain? The site is www.planetdj.com. The user is sent to secure.planetdj.com upon beginning check out. (Feel free to see for yourself).
This is the current code we have implemented.


var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-605157-1']);
_gaq.push(['_setDomainName', 'none']);
_gaq.push(['_setAllowLinker', true]);
_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);
})();

All of our conversions are listed as (direct) / (none).

It's not a referral issue, which is why I ask.

Your help would be awesome. Thanks! Great article!!

August 24, 2011 5:02 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Ken: I would recommend something along these lines:

var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-605157-1']);
_gaq.push(['_setDomainName', 'planetdj.com']);
_gaq.push(['_addIgnoredRef', 'planetdj.com']);
_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);
})();

These modifications will track visitors as they move across subdomains of planetdj.com. As long as everything is on planetdj.com, there's no reason to implement cross domain tracking modifications (_setDomainName('none') or _setAllowHash(false), _setAllowLinker(true), etc.).

August 25, 2011 7:28 AM

Ken Holden said:

Yeah that still didn't work. Would there be interference with the cookies? All our conversion traffic is still labeled as (Direct)/(none).

Care to take a peek? Feel free to start the checkout process, as I feel that's where the issue starts.

August 25, 2011 5:28 PM

HopeThisHelps said:

Note that _setAllowHash() has now been deprecated:

http://code.google.com/apis/analytics/docs/gaJS/gaJSApiDomainDirectory.html#_gat.GA_Tracker_._setAllowHash

and the recommendations on the Google site are now a lot closer to the above. I think they are listening ;-)

September 9, 2011 4:14 AM

David said:

Here is the situation our websites share a main navigation / design thus you can easily navigate between 'www.a.com', 'www.b.com' and 'www.c.com' we also have two subdomains of 'www.a.com' that each website uses for quotes & sales those subdomains are: 'secure.a.com' and 'sale.a.com'.

So if you are on 'www.a.com' and click a main navigation item you could go to 'www.b.com' once there say you add an item to your shopping cart you are take to 'secure.a.com'

Here is the solution we have implemented:

On each domain / subdomain we have placed this code:

_setDomainName is the only thing that changes and reflects the domain or subdomain you are on i.e. in this case ".a.com" on the other domains / subdomains it reads ".b.com", ".c.com", ".secure.a.com" and ".sale.a.com".

var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-XXXXX-1']);
_gaq.push(['_setDomainName', '.a.com']);
_gaq.push(['_setAllowLinker',true]);
_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);
})();

$('a').click(function() {
var url = $(this).attr("href");
if (url)
{
if (url.substring(0, 4) == 'http' && url != '' && url != '#' && url.toLowerCase().indexOf('youtube') {
if (url.substring(0, 4) == 'http')
{
_gaq.push(['_link',url]);
location.href = url;
}
return false;
}
}
});

Here are the questions:

We have noticed a large bump in average time on site, why, and how do we correct this?
Have we setup the code properly for multiple domain tracking & subdomain tracking?

September 16, 2011 10:49 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@David: The code looks reasonable. The _setAllowHash method has been deprecated; it's no longer necessary for cross-domain tracking, but it doesn't hurt much to leave it in. It also looks like you'll potentially be tagging all outbound links, not just the ones to your other domain, but it is easier to implement this way than to check each link against the list of your domains before tagging.

The bump in average time on site makes sense because you're maintaining the session across domains whereas before the session would break as you moved from domain to domain. For example, if you spent 3 minutes on a.com, 3 minutes on b.com, and 3 minutes on c.com, your average time on site in the old model would be 3 minutes, but in the new model it would be 9 minutes.

September 16, 2011 11:27 AM

Nick Budden said:

Hi Jeremy,

Thank you for the great post, I've been search for something like this for quite some time. I'm running a Wordpress network using subdomain installs, and currently all of my sites are being tracked using a single profile. What I hope to accomplish is to have one profile that tracks my primary domain AND my subdomains, and also to have an individual profile associated with each of my individual subdomains. I have a relatively small number of subdomains, and can customize my code for each if needed (i.e. my wordpress users cannot create their own subdomains...the solution does not need to be very dynamic). What would you suggest as the best solution for this?

Again thank you for the article!

October 5, 2011 3:50 PM

Kamran Jamshidi said:

This has been bookmarked, informative and well explained.

Using: _gaq.push(['_addIgnoredRef', 'example-petstore.com']); to filter own things away is useful.

Same goes with search engine reports etc from analytics, you get more clean data using features like:
_gaq.push(['_addIgnoredOrganic', 'www.mydomainname.com']);

October 10, 2011 6:02 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

While it's possible to track everything with a single account number and create the profiles for individual subdomains using filters, it probably makes the most sense to set up a second tracker for each subdomain with a separate account number. The reason is that there are types of hits that cannot be easily excluded using filters, which would show up in all of your profiles unless you took additional measures. This behavior is not well-defined, so you are best off using separate accounts.

Note, however, that these can simply be sub accounts within your main GA account. The profile for your main site might use UA-12345678-1, while the profiles for your subdomains might use UA-12345678-2, UA-12345678-3, etc. Also, the code for each subdomain should probably have the same subdomain modifications as your global tracking code unless you have specific reasons for not doing so. This can help to avoid subtle issues like having global tracking code that includes a leading period on your main site along with tracking code just for the main site that has no subdomain modifications, but in fact includes subdomain tracking that does not use the leading period by default, resulting in a hash conflict.

October 11, 2011 8:04 AM

justin brock said:

Great article, Jeremy.

Google recently updated the subdomain tracking video on Conversion University. In it they advise the leading period. http://services.google.com/analytics/breeze/en/domains_subdomains/index.html

Is your advice still not to use the leading period for those of us who only have subdomains, as opposed to lower-level subdomains?

October 13, 2011 12:20 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Justin: Yes, I still prefer to not use the leading period in situations where there are no lower-level subdomains. Lower-level subdomains are the only situation where a leading period is required. Not including the leading period tends to result in more forgiving tracking code. If someone manages to put up a page without code or the incorrect code, if they launch a website optimizer test, or if they were previously not previously doing subdomain tracking and update their code to include subdomain tracking modifications--all of these situations are handled much better without the leading period.

October 13, 2011 1:35 PM

Dan Lyons said:

Hi Jeremy,

Here's the issue I'm trying to solve:

I have multiple sites with different product catalogues.

SiteA.com - primary site. All shopping cart conversions happen through here. It has multiple subdomains.

SiteB.com - separate domain with no subdomains, has online store. But when an item is "added to cart" on this site, it sends the visitor to SiteA.com to complete the purchase. There is a unique "added to cart" page on SiteA.com that a visitor only sees if they came from SiteB.com - think of it as SiteA.com/cart/SiteBcart-addedtocart. This means anytime we see a pageview of SiteA.com/cart/SiteBcart-addedtocart in the GA reports, it means they were on SiteB and added something into their cart.

We're collecting all data into one profile - this includes SiteA.com and its subdomains and SiteB.com. Code we're using on SiteA.com and its subdomains is as follows:

var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-123456-1']);
_gaq.push(['_setDomainName', 'sitea.com']);
_gaq.push(['_setAllowHash', false]);
_gaq.push(['_setAllowLinker', true]);
_gaq.push(['_trackPageview']);
_gaq.push(['_trackPageLoadTime']);

SiteB.com code:
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-123456-1']);
_gaq.push(['_setDomainName', 'siteb.com']);
_gaq.push(['_setAllowHash', false]);
_gaq.push(['_setAllowLinker', true]);
_gaq.push(['_trackPageview']);
_gaq.push(['_trackPageLoadTime']);

We've tagged all links sending someone from siteb.com to sitea.com with linkbypost.

The issue: while we're tracking visitors successfully on both domains and subdomains, it seems the cookie is getting dropped when an item is placed in the cart on SiteB.com. When I look in the content report and segment down everyone who saw SiteA.com/cart/SiteBcart-addedtocart (visitors I know could only have come from siteb.com to sitea.com after placing an item in their cart) and then use a secondary dimension to identify their source, I'm seeing them as referrals from SiteB.com. I would also expect their landing page to be somewhere on SiteB.com, but landing page is showing up as SiteA.com/cart/SiteBcart-addedtocart.

Would appreciate your thoughts on why the cookie might be getting dropped in this instance.

Thanks!

October 15, 2011 10:42 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Dan: When you tag the links from one domain to the other, the cookie information from the first domain is passed to the second domain through the query string. Oftentimes with carts, these query parameters can become corrupted or may be stripped from the final URL altogether. You would need to confirm that this isn't happening. If it is, then there may be a way to work around it, but it will likely be rather complicated.

October 17, 2011 8:47 AM

ryan said:

Great article. Now for the code you recommend.... Does that go on both the main url and the subdomain? Thanks. Ryan

November 2, 2011 2:10 PM

Kim K said:

If the link to open the subdomain opens in a new window, will that cause a new session to be started? I have the correct codes on the domain and subdomain, but I see that a cookie is being writtem for the subdomain and it doesn't contain the original referrer data. Want to tell my client that they should open the links to the subdomain in the same window. I have never run across this particular "flavor" of setup, although I have coded up dozens and dozens of cross domain tracking setups.

November 23, 2011 2:47 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Kim: Opening the subdomain in a new window should not affect cookies. If cookies are being written improperly, then that means there is some issue with the Google Analytics Tracking Code on the subdomain. Even if the code on the subdomain is correct, it's possible that Google Website Optimizer code, Google Analytics Tracking Code from another vendor, or 3rd party code with built-in Google Analytics Integration might create a second second set of cookies for the subdomain.

November 28, 2011 9:08 AM

Nate said:

Great Post. Quick question. We are tracking multiple subdomains and top level domains on one tag. I noticed a lot of self referrals and came across this post. But have discovered something else. My issue is with the subdomains. One subdomain did not get updated with the GA tag. It had no tag at all. This subdomain is commonly hit when passing between two other subdomains. With this tag being absent, how bad did we mess up our data over that time? So if the users path was as follows (and it always will be):

subdomainA.domain.com > subdomainB.domain.com > subdomainC.domain.com - what did this do to our data?

Obviously we got a referral from subdomainB when, and lost our correct referral information I assume, and did not get page views on subdomainB, but did we also inflate visit count? Did we get a visit when they landed on A and exit when they landed on B and then a new visit when they landed on C?

I know that's a little off topic of this post, but if you have some insight that would be great.

December 15, 2011 2:45 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Nate: In Google Analytics, a session ends when there has been more than 30 minutes between pageviews. When the session ends, this means that the next pageview will result in a new visit and that the referral information of the visitor is subject to being updated. If it's been less than 30 minutes, however, then the referral information will not update unless it's something other than a site referral (i.e. tagged or organic).

This means that you will only get self-referrals when the visitor has spend more than 30 minutes on subdomainB. This also means that whenever the source changes from something else to a self-referral, a new visit has resulted with a new landing page and the visit count has been inflated.

December 15, 2011 3:38 PM

Saul said:

Hi! Thanks for this useful article. I have a one domain and 2 subdomains with your code implementation. But I don't know how track visitors from one subdomain to another..I mean how many new visitors has come to a subdomain and then went to another subdomain for example.

Sorry for my english.

December 23, 2011 6:15 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Saul: This code is for tracking a domain and its subdomains as a single site. When this is implemented, traffic moving from one subdomain to another is not as visible as it would be with the default code. If it's more important for you to see the subdomains as separate sites, then it may be better to just stick with the default code. There are ways to set up two accounts in Google Analytics and track subdomains both ways, as separate sites and as a single site, but this can be tricky to get right. The main concern is that cookies will likely be shared on the main domain unless you make sure to always resolve to www and the account that tracks subdomains individually explicitly sets the domain name to the FQDN (e.g. _gaq.push(['t2._setDomainName', 'www.domain.com']); or _gaq.push(['t2._setDomainName', document.domain]);).

December 27, 2011 10:14 AM

Blanka said:

Hi Jeremy,

the article is great, although I still have troubles with setting the subdomains tracking. We have a big media site with multiple subdomains, but just one parent domain. After customizing the tracking code we got rid of self referrals, but we noticed a huge drop in pageviews, which just doesnt make sense to me. Is there any explanation of why that happens? The code was the following:

_gaq.push(['_setAccount', 'UA-XXXXXXX-1']);
_gaq.push(['_setDomainName', 'mydomain.com']);
_gaq.push(['_trackPageview']);

Thank you!

January 2, 2012 7:31 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Blanka: There shouldn't be a drop in pageviews, so that suggests a configuration issue. One possibility is that the _setDomainName code may be incompatible with some of the subdomains. For example, you might have mydomain.co.uk, or mydomain.someotherdomain.com. Also, if you have multiple levels of subdomains, such as sub1.sub2.mydomain.com, then you'll need to use .mydomain.com instead of mydomain.com. These types of situations all result in no pageviews being generated for the affected subdomain.

January 3, 2012 11:27 AM

Jens said:

Hi Jeremy,

Several days ago I submitted a comment. Since thena couple of other comments have been published, but not mine. Is there a chance my comment ended up in the spam list? I would be really interested to get your feedback on a couple of my questions...

Thanks, Jens

January 3, 2012 7:23 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Jens: I searched for your other comment, but I wasn't able to find it (not even in the spam list). If you wouldn't mind reposting your questions, I would be happy to answer them.

January 4, 2012 8:22 AM

AB said:

This is a very useful post.

A couple of questions:

We were previously using setdomain without a period before the domain name. When we adjusted the GA code for subdomain tracking we then ADDED a period inadvertently.

We noticed that both direct traffic and goal completions increased tremendously.

Is this because users were likely dually cookied and goal completions fired twice?

Thanks,

February 1, 2012 12:41 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@AB: I'm not sure why goal completions would go up, but switching from non-leading period to leading period causes a cookie reset, which results in an increase in direct traffic. Leading period and non-leading period cookies are completely incompatible; each destroys the other.

February 6, 2012 2:55 PM

AB said:

Paid traffic is also showing as direct. Would adding the leading period resolve this issue?

Thanks,

February 7, 2012 10:37 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@AB: Consistency is key. In most cases, it doesn't really matter whether or not you use the leading period, but it does matter that you do the same exact thing on every page of the site. If you have some pages with the leading period and some without, that will seriously affect tracking. Also, any other GA based script on the site needs to be consistent as well. For example, if you're running a GWO test on the site, the same modifications need to be made there as well, including urchin.js style modifications (i.e. _udn = ".example.com";). Sometimes third party scripts will include their own GA tracking, which typically needs to be disabled to avoid interfering with your own code.

Paid Traffic showing up as direct could also be a result of redirects stripping the tags or landing pages with missing or incorrect GA code. For AdWords, you also need to make sure that autotagging is enabled, that your Adwords and Analytics accounts are linked, and that cost data has been applied to all relevant profiles.

February 7, 2012 10:53 AM

Abhijeet Kotwal said:

Hi,

I have a website and a blog which I'm tracking using GA.

We are using following accounts to track the site and the blog (sub domain)

For the main website example.com: UA-1234567-1

For the blog.example.com: UA-1234567-2

The problem is currently, I have to see two separate GA reports and Google is treating Traffic separately.

What I need is, the traffic to the website and blog should be considered as a single source of traffic and
single Report where I can monitor Source, Audience, Content, etc.

P.S. The Website is hosted separately and blog is on WordPress.

Please suggest a solution.

Thanks
Abhijeet

February 9, 2012 4:05 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Abhijeet: You should change the code on the blog so that it uses UA-1234567-1 instead of UA-1234567-2. You'll also need to modify the code on both the blog and the main site for subdomain tracking. Usually this means adding a line of code immediately after the _gaq.push(['_setAccount', 'UA-1234567-1']); line that looks like this:

_gaq.push(['_setDomainName', 'example.com']);

The code may be different depending on the version of GA you have up on the site. If you're using a WordPress plugin for GA, there should be an option to specify the domain as "example.com". I believe it's called "Domain Tracking" under advanced settings.

February 9, 2012 8:48 AM

TW said:

First of all, thank you for this amazingly useful article. Good info is tough to find on this subdomain tracking topic.

My question: I am currently developing a new site (brand new) that will have upwards of 15 subdomains. Since a lot of your advice here deals with those who had previous (no leading period) setups, would you still recommend the no-leading-period setup to me even though I am starting new?

I'm simply trying to figure the best way to track all 15 subdomains in one profile while still able to differentiate between the subdomains in traffic reports.

Any advice is greatly appreciated - thanks!

February 9, 2012 11:56 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@TW: I still prefer no leading period for new setups as long as there aren't multiple levels of subdomains because it gives you a more forgiving setup. For example, a person may set up a Google Website Optimizer test on the site and forget to modify the code for subdomains. If you use the leading period, visitors who get entered into the test will likely have their cookies thoroughly thrashed, leading to invalid data in GA. If your site doesn't use the leading period, then while the GWO setup is not ideal, you have a greater chance of keeping your GA data intact. Similarly, if someone sets up another page or subdomain and forgets to add subdomain modifications to the tracking code, you're more likely to be OK if the rest of your site does not use the leading period than if it does.

As far as differentiating between subdomains in the traffic reports, you can do this for the most part using advanced filters. Advanced filters can let you see all the visits that touched a particular subdomain. It will also include pageviews from other subdomains if they were part of that visit.

If you need to distinguish between subdomains at the pageview level, then I would use an advanced filter to add a prefix to request uri indicating the subdomain. For example, you can set it up so that blog.example.com/index.html will show up in the reports as /blog/index.html. This can be done with a single advanced filter, or with multiple filters if you have longer subdomains that you want to shorten in the page-level reports.

February 9, 2012 12:25 PM

TW said:

Jeremy: Many thanks!

So, to make sure I understand your advice 100%, you're saying:

1) Set up tracking code on all 15 subdomains the same way:

//Tracking code customizations only
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-12345-1']);
_gaq.push(['_setDomainName', 'example-petstore.com']);
_gaq.push(['_addIgnoredRef', 'example-petstore.com']);
_gaq.push(['_trackPageview']);

2) Distinguish between subdomains at the pageview level through advanced filtering / custom reports

If you feel like giving me additional insight into the best way to set up that advanced filter, I'm all ears.

Thanks again!

February 9, 2012 3:55 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@TW: 1. Yes. 2. Advanced Segmentation and standard filters on the profile. The following is one way to set up the filters:

http://code.google.com/apis/analytics/docs/tracking/gaTrackingSite.html#profilesKey

February 10, 2012 8:28 AM

TW said:

Again: Many thanks!

February 10, 2012 2:50 PM

Abhijeet Kotwal said:

Hi,

Thank you very much for the help!

After your feedback I implemented the following code:

var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-1234567-1']);
_gaq.push(['_setDomainName', 'mydomain.com']);
_gaq.push(['_trackPageview']);
_gaq.push(['_setAllowAnchor', true]);

(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);
})();


I implemented this code for mydomain.com and blog.mydomain.com (both hosted seperately)

But after this code implementation the Bounce Rate has drastically jumped from 20%+ to 60%+... For most of the pages on mydomain.com existing pages.

Could you please tell me how do I fix this issue?


Thanks,
Abhijeet

February 13, 2012 11:33 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Abhijeet: Make sure you include _gaq.push(['_addIgnoredRef', 'mydomain.com']); as well. That's not likely the cause of the bounce rate increase, but it's worth adding regardless. It sounds like there may be some rogue code on the site that's no longer compatible with your main tracking code. You can use a tool like httpfox and see if more than one __utm.gif hit is being generated per page. If that doesn't turn anything up, check your browser reports and see if the bounce rate is affecting only one browser. If it's an IE issue, there are IE specific tools you can use to view hits and cookies to try to determine what's going on. If nothing else, it may be worth rolling back the code temporarily until you can determine what's going wrong in a test environment.

February 14, 2012 8:22 AM

Domenico said:

Hi Jeremy,

thanks for this great article.

I have got an issue: I have got an existing main domain (say example.com) which has been collecting data for a couple of years and I now need to set up a third level domain (say something.example.com) within the same UA. I've followed your instructions as far as the third level domain is concerned so the code looks like

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

and set up a brand new profile under Google Analytics with a filter as "Include only traffic from the domains that are equal to something.example.com"

I have modified the tracking on the main domain site as follows

_gaq.push(['_setAccount', 'UA-XXXX-Y']);
_gaq.push(['_setDomainName', 'example.com']);
_gaq.push(['_addIgnoredRef', 'example.com']);
if(condition == true)
{
_gaq.push(['_setCustomVar', 1, 'CustomVarName', CustomVarValue, 2]); // I need this for some special situations
}
_gaq.push(['_trackPageview']);

but the main domain tracking has immediately dropped to 0, while on the second profile has not been collected at all.

What have I done wrong?

Thanks,
Domenico

March 14, 2012 10:53 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Domenico: I don't see anything wrong with the code you've set up. The behavior sounds like there may be an issue with the domain string you're passing to _setDomainName. If this string does not match the root level domain, then your tracking won't work at all. This could be a typo, or perhaps using .net instead of .com or something along those lines. Also note that while with _addIgnoredRef you could pass just 'example' instead of 'example.com' without any ill-effects, the same is not true of _setDomainName.

As far as the filter is concerned, I generally don't trust any of the pre-built filters, but always use a custom filter with the correct regex. In this case, I'd use a custom include filter on the hostname field with a value of "^something\.example\.com$".

March 14, 2012 11:47 AM

Domenico said:

Unfortunately there was no typo and everything seemed correctly set up, at least to me.

I'll give it another try and hope..

Anyway, thanks for your help.
Domenico

March 14, 2012 1:33 PM

Matt said:

Jeremy,

Great post and seriously impressive that you've responded to every commenter! So here's another one: after implementing this code a few months ago I've reduced the amount of self referrers by about 97% BUT I'm still seeing enough to believe that something still needs to be tweaked. First question, can you every totally eliminate self referrers? Second, based on this code do you see any obvious problems or have any suggestions:

I have a www.domain.com and info.domain.com. Code is the same on both:


try { var pageTracker = _gat._getTracker("UA-1234567-1");
pageTracker._setDomainName("domain.com");
pageTracker._trackPageview();
var supplementalTracker = _gat._getTracker('UA-1234567-2'); supplementalTracker._trackPageview();
} catch (err) { }


notice that I'm also pushing data into a second profile as per a client's request. Finally I didn't use addIgnoredRef and if you think that's the solution please let me know.

Thanks

March 30, 2012 11:59 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Matt: I would use _setDomainName("domain.com") for supplementalTracker as well and use _addIgnoredRef("domain.com") for both. That should take care of any lingering self-referral issues.

I think it's possible, but very difficult, to eliminate all self-referrals. If there are a few lingering self-referrals that make up less than 1% of your overall traffic, especially if also less than 1% of key visits (e.g. converting visits), then it's probably not worth chasing down the remaining fraction of a percent. For complex sites, the bar may be higher than 1%.

March 30, 2012 1:01 PM

Matt said:

Thanks Jeremy! Can you provide some reasons why it may be impossible to remove all self-referrals. The only reason I can think of is old cookies from pre-cross domain tracking modification Visitors.

March 30, 2012 2:15 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Matt: That's one reason. Other reasons include cached pages or pages with old/rogue code.

March 30, 2012 3:22 PM

Maggie said:

Hi Jeremy,

Using your article, we recently updated our GA tracking code to the following:
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-111111-1']);
_gaq.push(['_setDomainName', '.domain.com']);
_gaq.push(['_addIgnoredRef', 'domain.com']);
_gaq.push(['_trackPageview']);

Now we need to implement cross-domain tracking as well. Should we just add the _gaq.push(['_setAllowLinker', true]); line, or we should remove the _addIgnoredRef?

April 5, 2012 7:29 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Maggie: Just add the _gaq.push(['_setAllowLinker', true]); line.

April 5, 2012 8:07 AM

Newbie said:

Hi Jeremy,

Thanks for the great article, it's quite a puzzle getting your head around all these settings to be honest. I'm currently reviewing a proposed implementation (below) which requires the referral data between subdomains to be captured in a separate account for each subdomain and the cross domain data to be captured in one overall account. Do you see any reason why this wouldn't work?


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



_gaq.push(['._setAccount', 'UA-xxxxxxx-1']);
_gaq.push(['._setDomainName', '.domain.com']);
_gaq.push(['._trackPageview']);

April 23, 2012 11:39 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

In order for this work, your main domain must resolve all requests to www.domain.com. If it can resolve/does resolve to just domain.com instead, then you will have cookie conflicts for those pages.

I would also recommend using the following instead:

var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-xxxxxxx-1']);
_gaq.push(['_setDomainName', document.domain]);
_gaq.push(['_trackPageview']);



_gaq.push(['._setAccount', 'UA-xxxxxxx-1']);
_gaq.push(['._setDomainName', '.domain.com']);
_gaq.push(['._trackPageview']);

Passing document.domain set cookies to fully qualified domain name without turning off cookie hashing. Passing 'none' also sets cookies to the fully qualified domain name, but it turns off hashing too. The hash allows the the code to determine the correct set of cookies to read from. When it's turned off, the code will read the first set of cookies it finds, which may be the wrong set.

Also, if you don't have any lower-level subdomains (e.g. my.sub.domain.com), and don't expect to have any, then you should use 'domain.com' instead of '.domain.com' This will make your code a bit more resilient if, say, someone puts some rogue code on the site or launches a Google Website Optimizer test.

April 23, 2012 12:19 PM

Jackye said:

Hi Jeremy..
It's so hard to make that works.
We have 2 sub-domains here, and when I put:

_gaq.push(['_setDomainName', '.example-petstore.com']);
_gaq.push(['_setAllowHash', false]);

It get a lot of self referrals. =/
But I didn't understand your suggestion quite sure..
So How can i do it?
Something like that:

_gaq.push(['_setDomainName', 'domain.com']);
_gaq.push(['_addIgnoredRef', 'domain.com']);
_gaq.push(['_trackPageview']);


What will happen with sub1.domain.com and sub2.domain.com? Should I put the same code? Or do I need to put a change on them too?

Thank you so much, these settings are so hard to understand =/

April 26, 2012 4:09 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Jackye: Yes, the code you posted should work:

_gaq.push(['_setDomainName', 'domain.com']);
_gaq.push(['_addIgnoredRef', 'domain.com']);
_gaq.push(['_trackPageview']);

You would use this same code on both sub1.domain.com and sub2.domain.com.

April 26, 2012 4:55 PM

Jackye said:

Thanks!

Another quick one:

Is there any really difference between this:

_gaq.push(['_setDomainName', '.domain.com']);
_gaq.push(['_addIgnoredRef', '.domain.com']);
_gaq.push(['_trackPageview']);

and this:

_gaq.push(['_setDomainName', 'domain.com']);
_gaq.push(['_addIgnoredRef', 'domain.com']);
_gaq.push(['_trackPageview']);

the "." before domain.com really matters?
our domain here is www.domain.com with subdomains: sub1.domain.com and sub2.domain.com

Thanks again!

April 27, 2012 8:51 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Jackye: Yes, there is a difference. If you use the leading period (the "." before domain.com), then your cookies will be set in such a way that they'll be accessible to lower level subdomains (e.g. lowersub1.sub1.domain.com). Most people do not have lower level subdomains, so this is usually unnecessary. Furthermore, cookies set without the leading period are more compatible with cookies set without any subdomain at all.

So if you have the option to not use the leading period, this is usually the way to go as it makes your code more resilient. For example, someone might launch a Google Website Optimizer test on the page without adding subdomain code, or you might use a 3rd party plugin that also happens to have Google Analytics tracking enable. With these types of situations, there's a greater chance that your tracking will be just fine if you don't use the leading period. Otherwise, both of these scenarios would result in a cookie conflict, with the end result being that your cookies would be destroyed and recreated with incorrect referral information.

For _addIgnoredRef, you should not use the leading period regardless of whether or not you use the leading period for _setDomainName. _addIgnoredRef does a straightforward string comparison between the current domain and the string you pass to it. So if someone can get to, say, domain.com without the www, then _addIgnoredRef won't catch it if it has the leading period. You can, in fact, simplify _addIgnored ref and just pass "domain" if you felt like it. Of course, this would potentially ignore domain.org or domain.net as well, but it's really just to illustrate the fact that _addIgnoredRef just checks to see if the string passed to it is a substring of the current domain.

April 27, 2012 9:35 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Jackye: Yes, there is a difference. If you use the leading period (the "." before domain.com), then your cookies will be set in such a way that they'll be accessible to lower level subdomains (e.g. lowersub1.sub1.domain.com). Most people do not have lower level subdomains, so this is usually unnecessary. Furthermore, cookies set without the leading period are more compatible with cookies set without any subdomain at all.

So if you have the option to not use the leading period, this is usually the way to go as it makes your code more resilient. For example, someone might launch a Google Website Optimizer test on the page without adding subdomain code, or you might use a 3rd party plugin that also happens to have Google Analytics tracking enable. With these types of situations, there's a greater chance that your tracking will be just fine if you don't use the leading period. Otherwise, both of these scenarios would result in a cookie conflict, with the end result being that your cookies would be destroyed and recreated with incorrect referral information.

For _addIgnoredRef, you should not use the leading period regardless of whether or not you use the leading period for _setDomainName. _addIgnoredRef does a straightforward string comparison between the current domain and the string you pass to it. So if someone can get to, say, domain.com without the www, then _addIgnoredRef won't catch it if it has the leading period. You can, in fact, simplify _addIgnored ref and just pass "domain" if you felt like it. Of course, this would potentially ignore domain.org or domain.net as well, but it's really just to illustrate the fact that _addIgnoredRef just checks to see if the string passed to it is a substring of the current domain.

April 27, 2012 9:35 AM

Rita said:

I'm trying to understand this (eek) and set up my GA. I have a .com site such as: www.bookstore.com and on that same domain have added www.bookstore.com/blog. (wordpress) What I don't understand is; is the blog considered the subdomain? And would I put the .com site as the domain and leave the blog as the subdomain? Or would I put the .com/blog and leave the main .com as the subdomain ? Then, what exact code would I add to the generated code so that it would all track properly ? Thanks for keeping it simple. :)

June 1, 2012 12:44 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Rita: What you have is a subdirectory. There's no special code needed in order to track your subdirectory in addition to your main site. The standard GA code should work fine.

If your wordpress blog was on blog.bookstore.com, instead of www.bookstore.com/blog, then you would have a subdomain and would need to modify your code.

June 1, 2012 1:21 PM

Rita said:

@Jeremy, okay my website is a eg. www.bookstore.com and my blog is www.bookstore.com/blog so you said that would make it a subdirectory and no need to update the code. Good. So, my question is; what do I put in the profile settings URL and the property settings URL would I only ever need to put eg; www.bookstore.com and then the .com/blog part would automatically pick up in the stats ? So, should property and profile URL's match ? That is what I need to know to finish signing up with my proper settings. Thanks so much!

June 3, 2012 1:22 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

GA does not consider a subdirectory to be a separate site, even if the hosting for that subdirectory is different for the rest of your site. It will pick up on your subdirectory automatically. If you decide to create a profile that only reports on your blog subdirectory, you will need to add a filter to that new profile to only include traffic to that subdirectory. The profile name should probably include the subdirectory as well, only to be able to distinguish it from your main profile, but the subdirectory does not need to be included as part of the URL, and you should not create a new web property for the subdirectory, but rather use the existing web property for your main site.

June 4, 2012 8:50 AM

Nathan Arthur said:

Hello, Jeremy!

I've got a question for you: Will subdomain tracking work when the main domain and the subdomain use different versions of the GA tracking code? I'm using an eCommerce service (store.mydomain.com) which uses legacy ga tracking code, whereas my main site (mydomain.com) uses the new asynchronous version.

The problem I'm trying to fix is that any traffic that came from my main site, to the store, and then ended in a purchase, shows as direct traffic. The original referral data isn't being preserved.

My modified code looks like this:

mydomain.com/.org code:

var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-xxxxxxx-y']);
_gaq.push(['_setDomainName', 'mydomain.com']);
_gaq.push(['_addIgnoredRef', 'mydomain.com']);
_gaq.push(['_addIgnoredRef', 'mydomain.org']);
_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);
})();

store.mydomain.com code:

var pageTracker = _gat._getTracker('UA-xxxxxxx-y');
pageTracker._addDevId('o5cUG');
pageTracker._setAllowLinker(true);
pageTracker._setDomainName('none');
try{pageTracker._setDomainName('mydomain.com');
pageTracker._addIgnoredRef('mydomain.com');
pageTracker._addIgnoredRef('mydomain.org');}catch(e){};
pageTracker._trackPageview();

What am I doing wrong?

June 14, 2012 2:21 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Nathan: You can use different versions of the GA tracking code on different pages. The issue you're having is that visitors are going from a .org site to a .com site. This is a cross-domain situation, which means that you'll need to modify your code for cross domain tracking:

https://developers.google.com/analytics/devguides/collection/gajs/gaTrackingSite

More specifically, you should not have both _setDomainName('none') and _setDomainName('mydomain.com'). I would use the latter on both mydomain.com and store.mydomain.com, and use _setDomainName('mydomain.org') on mydomain.org. You should also include _setAllowLinker('true') on all three sites and make sure to use _link or _linkByPost as appropriate on any links or forms that go from .org to .com or vice versa.

June 15, 2012 8:30 AM

Nathan Arthur said:

Thank you so much for the reply!

So .org is just an alias of our .com address. Anything available on the .com is available on the .org. Is there a way to make Google Analytics play nice with this, and not have to worry about tracking then like they were two different sites? Would using only "_setDomainName('mydomain.com');" achieve that?

I would really like to avoid having to worry about cross-domain tracking if at all possible. We've even thrown around the idea of just setting up a site-wide 301 redirect from .org to .com if it would take the cross-domain aspect out of the picture. I'd rather not have to resort to that, though.

June 18, 2012 8:59 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Nathan: 301 redirecting from .org to .com would avoid the cross-domain situation. Alternatively, you could also have a store.mydomain.org in addition to store.mydomain.com. Then you would just need to be consistent with your links and maintain separate tracking codes for the .org and .com sites, since the _setDomainName line would be different for the .org and the .com sites.

There are also scripts which can be used to tag all of the links going between the two domains. It's still considered cross-domain, but it can take some of the pain out of the setup. It's also not too hard to write your own script, especially if you already have a JavaScript library like jQuery on the site. The trickest part is getting such scripts to work for edge cases such as links and forms with multiple redirects and things like that. If you have full control over all sites, then you may be able to eliminate those types of situations if any exist, which can greatly simplify cross-domain tracking.

June 19, 2012 8:06 AM

Stuti said:

Thank you so much for this.
Made my day
God bless you :)

July 30, 2012 1:55 PM

vincent said:

hi Jeremy:

i have also encounted the self-referral issue, and should it add the the modify code "_gaq.push(['_addIgnoredRef', 'sister-site.com']);" to all pages in each subdomain? or add only one statement in the front page

November 2, 2012 11:16 PM

vincent said:

hi jeremy

i also have the self-referral issue, and i followed your instrcution adding the modified code :"_gaq.push(['_addIgnoredRef', 'sister-site.com']);"
in each pages of our maindomain. but the problem still exist.

should i add the modified code for each pages under each subdomain? or just add only a statement on the front page of our main domain?

as u menetioned in our article :"This also eliminates the need to add a separate _addIgnoredRef statement for each subdomain."

so confused..

November 3, 2012 12:00 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@vincent: You should add the same modification to all subdomains as well.

There is a common misconception that you need to add a separate _addIgnoredRef statement for each subdomain:

// BAD EXAMPLE
_gaq.push(['_addIgnoredRef', 'www.sister-site.com']);
_gaq.push(['_addIgnoredRef', 'blog.sister-site.com']);
_gaq.push(['_addIgnoredRef', 'shop.sister-site.com']);

Instead, only one line is necessary site-wide, regardless of how many subdomains you have:

// GOOD EXAMPLE
_gaq.push(['_addIgnoredRef', 'sister-site.com']);

Note also that the official documentation still recommends:

// BAD EXAMPLE
_gaq.push(['_addIgnoredRef', 'www.sister-site.com']);

which is still wrong since it won't match requests for your domain without the 'www', nor for subdomains.

November 5, 2012 7:55 AM

Jasmina said:

Hello

I want to track www.example.com and not other subdomains, e.g. static.example.com. To that effect I've tried setting _gaq.push(['_setDomainName', 'www.example.com']); but this is not working out as the cookie is still set to example.com so it's also set for static.example.com

How would you recommend that this is implemented so that the cookie is only set for www.example.com and not for static.example.com or any other subdomain?

301 redirect is in place for example.com to www.example.com

November 7, 2012 6:23 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Jasmina: The line you're adding should work, so if you're having trouble with it, make sure you're adding it after the _setAccount line but before the _trackPageview line.

November 8, 2012 7:51 AM

Jasmina said:

Ta Jeremy, it became obvious as soon as I read your comment.

November 8, 2012 4:27 PM

Poulpator said:

Hi,
I have more than 200 subdomain.
And a need to know each unique visitor per subdomain.
Is there a way to view data per subdomain without creating a profile for each subdomain?

Regards from French Alps

November 20, 2012 11:36 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Poulpator: You can set up a custom report with Hostname as a dimension and unique visitors as a metric.

November 20, 2012 3:29 PM

Chris Eldredge said:

are any recommendations in this article now out of date?

thanks for the great article!

May 21, 2013 4:34 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

The code modifications recommended by this article for subdomain tracking are still up to date for ga.js.

May 22, 2013 8:09 AM

Pavel said:

Jeremy, sorry if this has already been answered before, but I couldn't find it in the 3 years of comments to this topic, so would appreciate if you could help me out.
We have a website with 3 language versions.
www.website.com for english
lang1.website.com for lang 1
lang2.website.com for lang 2

Currently we have a default tracking code installed which results in inflated visits, recorded under Referral section of google analytics.

Do we understand this correctly that adding
_gaq.push(['_addIgnoredRef', 'website.com']);
would eliminate those self-referrals?

So if originally the user came from Google to a www-version and then switched to lang1., then with the updated tracking code, Google Analytics would report that visit as a single visit originating from Google but would include two Domain Names under this visit which were visited by the user.

Hmmm, but then, that would be two visits, no?

Do you know, how would such a visit be reflected in the GA-report?

December 6, 2013 12:03 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Pavel: Assuming you're still using ga.js analytics, you will need both lines:

_gaq.push(['_setDomainName', 'website.com']);
_gaq.push(['_addIgnoredRef', 'website.com']);

December 9, 2013 12:42 PM

anna-lisa said:

Hi Jeremy, thanks for your helpful post. I have a question: I have a cross domain & subdomain issue, site A with subdomain A1/A2/A3 and so on, and the conversion/transaction occurs on Site B. I have set a duplicated complete profile for all visits to site A with a filter which includes all visits coming from subdomains. Then I have set single profiles for each subdomain with a filter including visits from each subdomain (filter Host name). On these single profiles I can't see any conversion/transaction. I presume it's because the filter includes only visits from subdomain, so visits (and conversions) from Site B are excluded.

Am I right? Is there a way to solve this problem?

February 28, 2014 5:38 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

If you track all of the domains and sub domains in a single view/profile, then you should be able to create custom advanced segments for each subdomain. Any filter solution would likely require a complicated set of 3 filters based on an indicator on Site B that lets you know which sub domain it's currently being used for.

March 3, 2014 9:04 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

If you track all of the domains and sub domains in a single view/profile, then you should be able to create custom advanced segments for each subdomain. Any filter solution would likely require a complicated set of 3 filters based on an indicator on Site B that lets you know which sub domain it's currently being used for.

March 3, 2014 9:04 AM

Damion said:

Brilliant! I just wish this post was written..... er, the last time I needed to have this as a reference! I had to cobble together a fix from those various inadequate, outdated, fuzzy articles you mention.

I've bookmarked this, and hopefully I'll remember its existence next time the sound of dying tracking is all around. Devs all too often give little thought to how tracking might be affected by their "quirky" subdomain (or even multi-domain) structure, and I'm hoping that this article might be able to solve a few problems before they spiral out of control. Thanks once again!

January 5, 2011 5:13 PM

Eric Polatty said:

If you go to the tracking code section under profile settings in your GA account, and click "one domain with multiple subodmains" under "what are you tracking", I notice the code Google generates for you to use does not include the _setAllowHash tag. But they tell you to include it in the Google Code article for subdomain tracking. I understand it's a free product - but I find Google's inability to make up their minds about how to use their own software frustrating to say the least.

January 6, 2011 9:51 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Eric: My guess is that the Google Code example includes _setAllowHash because it is on a page dedicated to cross-domain tracking. Unfortunately there's currently no Google Code page that just deals with subdomain tracking. I think we lost this during the transition from the traditional ga.js code to the async code, but I'm hopeful that this will be addressed.

The code that's generated from your Google Analytics account is better, but still suffers from the other issues I went over. The lack of an _addIgnoredRef line, or rather the lack of the logic behind the _addIgnoredRef line being executed for an appropriate _setDomainName call, is especially disconcerting since it implies that _setDomainName is sufficient for optimum subdomain tracking.

January 6, 2011 10:37 AM

Eric Polatty said:

@Jeremy - Most of the main Google Code article is on cross-domain situations, but there is a section "tracking across a domain and it's sudomains" and it has the _setAllowHash tag there.

January 7, 2011 10:26 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Eric: It's possible that since it was sandwiched between the other cross-domain examples that the _setAllowHash tag was added unintentionally. Regardless, it shouldn't be there for a subdomain only example.

January 7, 2011 10:32 AM

Mike Sullivan said:

Thank you! Thank you! Thank you!

We added (yet another) subdomain to our environment over the holidays and I tried (yet again) to get rid of the self-referrals. There's so much not-quite-right guidance out there!

Made your suggested changes and today, they have dropped WAY off!

January 7, 2011 11:50 AM

Adam said:

Great article. I'd just about given up on solving the self referrals issue.

Question: if your site uses both subdomains and lower level subdomains, should you use a leading period on both, or just your lower level subdomain pages?

January 7, 2011 12:05 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Adam: If your site has lower level subdomains, then you should use the leading period site-wide.

If you used the leading period on some subdomains and not on others, the hash codes for the cookies would be different, so your cookies would get destroyed every time you crossed from a page using the leading period to a page not using the leading period and vice versa. So regardless of whether you decide/need to use the leading period or not, you want to be consistent.

January 7, 2011 2:09 PM

david said:

Hi Jeremy,

This article of yours was definitely a nice reading.

I experienced myself lots of issues a few weeks ago when adding subdomain tracking to our site, following Google instructions. One of the main problems was a huge boost of direct traffic (we were using leading period, but we didnt use SetAllowHash).

I am willing to try your solution now. However, would you still recommend this implementation (no period and AddIgnoreRef) even for the traditional ga.js code?

January 10, 2011 7:20 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@David: Yes, I would recommend this solution even if you're using the traditional ga.js code. This would look something like the following:

var pageTracker = _gat._getTracker("UA-12345-1");
pageTracker._setDomainName("example-petstore.com");
pageTracker._addIgnoredRef("example-petstore.com");
pageTracker._trackPageview();

A sudden influx of direct traffic can result from going from no subdomain tracking to subdomain tracking with the leading period. Removing the leading period may help, but this depends on how long you've had the code with the leading period up. There aren't any hard or fast rules on this, but I would say that if you've only had the code with the leading period up for a month or more, you might be better off sticking with it at this point.

There's nothing inherently wrong with using the leading period. The main issue I have with it is that for a site that the hash code generated when you use the leading period is different than the one generated when you don't have subdomain tracking at all. If you've already been using the leading period for a significant amount of time, then switching your code to not use the leading period may be just as bad for tracking as switching to using the leading period in the first place.

Also, for a brand new Google Analytics installation, using the leading period is perfectly fine.

January 10, 2011 8:02 AM

David said:

Thanks for your advice, Jeremy. I will keep your considerations in mind and try your proposed subdomain tracking code.

We had the code with the leading period for just a couple of days. The breakage of the data was big enough to get quickly back to the older version, even though it was not taking into account the existing subdomains.

Hopefully I will get a chance to try your suggestions some day next week. Our site has a large amount of traffic, so after a few hours we will be ready to say if it is working or not. I will let you know ;)

January 10, 2011 10:19 AM

Cloga said:

Excellence article!Thank you!

January 10, 2011 10:46 AM

Cristina Chetroi said:

Hi Jeremy!
The _addIgnoredRef tip to minimise self-referrals is great, as they really are a pain. Thanks!

I also remember someone mentioning the inconsistency between the code GA console generates for subdomain tracking (no setAllowHash to false) and the official documentation.

We all wish domain hashing needn't be compromised. But the reality is that it often is - it's common that a client decides to introduce subdomains or other domains at a later stage and you need to tweak the snippet as the result.

So, when it happens, would it be possible to introduce some sort of cookie checkup for returning visitors and do some sort of merge instead of setting a second set cookies/destroying them?

January 12, 2011 5:19 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Cristina: It would certainly be possible to do that. I've done something similar to that before with cookies that were generated with _setNamespace, so it shouldn't be that hard. I have some other ideas about how this might be done as well, something I'm hoping to write about in a future post.

January 13, 2011 7:54 AM

Liz said:

would i use this customization on all subdomains and the top level domains? Or just all the subdomains I want to track - I will have about 4 or 5 of them.

Thanks

January 27, 2011 2:27 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Liz: I would recommend using the modification on all subdomains and top level domains. I have seen some cases where people wanted to track certain subdomains only so they could see traffic coming from other subdomains as referrals, but this is not an ideal setup. Inevitably someone also wants to track the other subdomains, which gives you strange mix of referrals from subdomains and original referral data to those subdomains showing up in your reports. Instead, you should track everything and use filters in Google Analytics to exclude the unwanted domains.

January 27, 2011 4:26 PM

Bernd said:

You wrote:
_gaq.push(['_setDomainName', 'example-petstore.com']);

Google says:
_gaq.push(['_setDomainName', '.example-petstore.com']);

(see the dot before domainname).

What is the difference?

January 30, 2011 2:16 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Bernd: The main differences are that:

1. Each generates a different hash, but not including a leading period has the same hash as no subdomain tracking at all.
2. Including a leading period works for sites with lower level subdomains (ex. buy.store.example-petstore.com).

Google includes the leading period to account for #2. The reason I don't include the leading period is because of #1. It feel that it's more likely that someone is transitioning their code from no subdomain tracking to subdomain tracking than that they have lower level subdomains.

So, as mentioned in the article, if you have lower level subdomains, or if you're setting up Google Analytics Tracking Code on your site for the first time, use the leading period. If you don't have lower level subdomains and you've had Google Analytics Tracking Code on your site for a while, then don't use the leading period.

January 31, 2011 7:54 AM

Bernd said:

OK, thank you very much, Jeremy!

January 31, 2011 1:33 PM

Nick said:

I'm a little confused. Your second point says that you have to use the leading period if you have lower level subdomains, but then at the end you said don't use if you don't have to.

Let's say I have example.com and store.example.com, would I want to use the leading period to track this properly?

January 31, 2011 5:52 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Nick: The only time you have to use the leading period is if you have lower level subdomains. For your example, the leading period is unnecessary for tracking this properly because you don't have any lower level subdomains. You'd have to have another level of subdomain tacked on to there, such as buy.store.example.com.

If you don't have lower level subdomains and you're setting up Google Analytics for the first time on a site, then you have the option to either use or not use the leading period. I tend to not use it as this tends to be more stable, again because the hash code is the same as if you didn't have subdomain tracking on the main domain. So if someone else sets up a Google Website Optimizer test on your homepage, for example, and forgets to add subdomain tracking modifications, this isn't as big of a deal if you had implemented subdomain tracking without the leading period.

The main benefit to using the leading period for new sites without lower level subdomains is that you'll have less people question your setup since it's closer to the Google recommendations.

For sites with existing Google Analytics Tracking Code that you want to update to use subdomain tracking code, not using the leading period will lead to a much smoother transition. Of course, if your site also has lower level subdomain, you'll have to bite the bullet and use the leading period anyway.

Whichever way you decide to go, make sure that you apply that decision consistently across your site. Having some pages that use the leading period and some that don't will wreak havoc on your site.

February 1, 2011 7:56 AM

Chris said:

I'm working on a WordPress MultiSite project which uses subdomain, some of which are mapped to other domains. So what I'm doing really is more in line with the Google example since its not just sub-domain tracking but cross-domain tracking. My question to you is is there any benefit to using _addIgnoredRef for cross-domain tracking? Or could it hurt in any way? I'm looking to reduce self referals as much as possible.

February 4, 2011 12:21 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Chris: Using _addIgnoredRef will still help some with preventing self-referrals. You should have one _addIgnoredRef statement for each root level domain. _addIgnoredRef only ignores a referral if there is previous referral data to fall back on.

So if you have any links between domains that aren't tagged with the proper linking parameters, this will show up in your reports as self-referrals, even if you use _addIgnoredRef. This is a good thing, because it provides visibility for fixable self-referrals.

If there is previous referral data, however, _addIgnoredRef will preserve it. This can be especially useful in situations where you can tag links to a third-party domain, but have trouble tagging links going back to the original domain.

February 4, 2011 8:33 AM

Rob said:

I tried using Google's subdomain tracking suggestion to no avail. For 1 day I did see in GA URL's from the subdomain but I have not been able to figure out how. I came upon this blog after discussing this with a GA expert who has been gracious enough to help us try a few options.

So I adjusted the subdomain code to look like this, per your suggestions:

var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-xxxxxxx-y']);
_gaq.push(['_setDomainName', 'cae-nyc.org']);
_gaq.push(['_addIgnoredRef', 'cae-nyc.org']);
_gaq.push(['_trackPageview']);


The primary/main Drupal-driven domain has this:


var _gaq = _gaq || [];
_gaq.push(["_setAccount", "UA-xxxxxxx-y"]);
_gaq.push(['_setDomainName', 'cae-nyc.org']);
_gaq.push(['_addIgnoredRef', 'cae-nyc.org']);
_gaq.push(["_trackPageview"]);

Now, a thing to note: we have 2 URL's that we use, hosted on a share GoDaddy account: caenyc.org and cae-nyc.org. (Notice a hyphen). The subdomain does NOT have a hyphen it' all advocacy.caenyc.org. I do not have access to an Apache httpd.conf file so I have to use GoDaddy's GUI/Total Domain Control to create the redirect. Could that be causing the problem? Can you peak at both domains & view their source?

Thanks!

Rob

February 8, 2011 9:44 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Rob: Your code should be different depending on which domain it's on. So on cae-nyc.org (with the hyphen), your code should look like the following:

var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-xxxxxxx-y']);
_gaq.push(['_setDomainName', 'cae-nyc.org']);
_gaq.push(['_addIgnoredRef', 'cae-nyc.org']);
_gaq.push(['_trackPageview']);

But on caenyc.org (without the hyphen), your code should look like the following:

var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-xxxxxxx-y']);
_gaq.push(['_setDomainName', 'caenyc.org']);
_gaq.push(['_addIgnoredRef', 'caenyc.org']);
_gaq.push(['_trackPageview']);

The value you pass to _setDomainName must match the domain it's on, otherwise the code will fail. This is also true when you're tracking both example.com and example.net.

I also don't know if visitors can go back and forth between cae-nyc.org and caenyc.org. If they can, then that falls under the realm of cross-domain tracking, which requires a completely different set of tracking code modifications. Still, you'll need to fix the _setDomainName line on caenyc.org to get any kind of tracking there at all.

February 8, 2011 1:03 PM

Rob said:

Sigh, I wish I had tried the obvious yep that worked. And yes people can go from the sub-domain to the main domain and vice verse.

So for example, an email campaign might start with the sub-domain. Then a person fills out the form on the sub-domain, and clicks on Home, which goes back to the main www domain.

Or, people will click on a link from www, e.g., on the home page, and go to the sub-domain, fill out the form, and may hit home. Does that mean cross-domain?

Also, using the sub-domain filter, the Content report is showing the paths with a leading / like this:

/advocacy.caenyc.org/site/apps/kb/cs/contactsearch.asp

or

/advocacy.caenyc.org/site/c.rwL4JlO7KzE/b.6421085/k.DF6F/Petition_to_Incoming_Schools_Chancellor_Cathie_Black/apps/ka/ct/contactus.asp?c=rwL4JlO7KzE&b=6421085&en=ftINKXMILiKPJ5PUJeILI3OLInKZI7OKJgIXK6OQKtK9F


I take it I can transform the URL with another filter?

February 8, 2011 4:53 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Rob: You only need to implement cross-domain tracking if a visitor can move across root level domains. Going from avocacy.caenyc.org to www.caenyc.org does not count as cross-domain because you're just moving from one subdomain of caenyc.org to another.

Going from avocacy.caenyc.org to www.cae-nyc.org, however, does count as cross-domain tracking and requires additional modifications to your code, as well as modifications to the links going between domains. Generally it's something to be avoided if at all possible.

In your situation, the easiest way to avoid the issue is to just 301 redirect visitors who request cae-nyc.org pages to the appropriate caenyc.org page. This eliminates the need for cross-domain tracking and dramatically simplifies your Google Analytics setup.

With regard to filters, yes, you can apply additional filters after the subdomain filter. Those filters will be applied to the modified URL instead of the original URL, so you can use this to change the URL to look exactly how you want it to in Google Analytics. Also, you may want to look at Exclude URL Query Parameters under the Main Website Profile Information to remove any unnecessary query parameters and clean up reporting even further. This is usually easier than using filters to remove the query parameters.

February 9, 2011 7:57 AM

Emily said:

I have multiple domains that I have the same UA# (cookmedical.com, cookbiodesign.com and cookartlab.com). These domains feed traffic between each other and so it would be helpful if I could track them as if they were all the same site to track users between the domains. Based on this information it sounds like I should add the following to all of the pages in all the domains:

_gaq.push(['_setDomainName', 'none']);
_gaq.push(['_addIgnoredRef', 'cookmedical.com']);
_gaq.push(['_addIgnoredRef', 'cookbiodesign.com']);
_gaq.push(['_addIgnoredRef', 'cookartlab.com']);

Am I understanding you correctly?

February 9, 2011 8:48 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Emily: The _addIgnoredRef lines may help with some self-referrals issues, but they're not directly related to cross-domain tracking.

Cross-domain tracking in Google Analytics is the sort of thing that really deserves a series of posts, but I'll try to summarize it as best as I can within this comment.

First, I generally avoid using _gaq.push(['_setDomainName', 'none']); because it does too much. _gaq.push(['_setAllowHash', false]); (no quotes around false) accomplishes the minimum for cross-domain tracking, so it's preferred.

Second, you'll also need to add _gaq.push(['_setAllowLinker', true]); (again, no quotes around true).

Third, you'll need to modify the links between domains. The easiest way to do this is to have the following onclick attribute in the link:

onclick="_gaq.push(['_link', this.href]); return false;"

This covers most scenarios, but not all of them. There will likely be additional nuances that these instructions won't handle. The official Google Code article may help with some of these.

Here are some other things to keep in mind:

1. _link invokes a javascript redirect, which means the referrer won't be available on the receiving page in IE. There are other ways to do this that preserve the referrer, but they are more advanced.
2. _linkByPost may work with forms that use GET instead of POST, but you'll have to specifiy true in the third parameter, that is:

_gaq.push(['_linkByPost', this, true]);

This passes query parameters through the anchor text instead of the query string. This means you'll also need to add _gaq.push(['_setAllowAnchor', true]); to your Google Analytics Tracking Code.
3. It's generally preferred to accomplish linking between domains in a more dynamic way. You might be able to build this into a template driven site, or use a script that modifies onclick attributes of links dynamically.
4. You should try to minimize redirects between domains. These will often do unintended things to query parameters and anchor text and make cross-domain tracking very difficult or impossible.

Because of all the complications involved in cross-domain tracking, you may want to consider purchasing a support plan to ensure that everything is set up correctly.

February 9, 2011 9:18 AM

Emily said:

Thanks that helps a lot. I talked to my developer about this and we're building a dynamic script to add the onClick function to the links that are moving between domains that we want to track together.
I agree that it would be best if we didn't have this highly related content on different domains and we are in the process of redesigning our overall site to include the pages that are currently on separate domains. In the mean time we really need to be able to see how users are moving through our sites.

Thank you for all your help!

February 9, 2011 10:44 AM

Eduardo Cereto said:

The argument that the leading dot can cause problems when you're changing a GA implementation is valid. But what's not clear in the post is your opinion about new implementations.

Since a new implementation doesn't have any already set cookie we should bother, than I think there's no drawback about using the leading dot.

I always use the leading dot in my new implementation, and will keep doing so.

I'm not only worried about the sub-sub-domains. But the leading dot feels more compliant with the RFC that specifies that the absence of it can cause Rejection of the cookie. I'm not sure how many browsers acctually comply to that statements, none I know of. Still I'd rather not take my chances.

http://www.ietf.org/rfc/rfc2109.txt

Quoting the RFC:
4.3.2 Rejecting Cookies
...
* The value for the Domain attribute contains no embedded dots or
does not start with a dot.

[page] 4
Domain=domain
Optional. The Domain attribute specifies the domain for which the
cookie is valid. An explicitly specified domain must always start
with a dot.

February 10, 2011 10:32 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Eduardo: I think that you can argue it either way for new Google Analytics implementations. I prefer not to use the leading period even for leading implementations (assuming of course that there aren't any sub-sub-domains). The reason is that this type of setup tends to be more forgiving when it comes to things such as rogue Google Website Optimizer tests where someone forgot to add subdomain tracking modifications.

If the RFC were an issue, then it seems like Google would have addressed this in the standard Google Analytics Tracking Code. As stands right now, if you don't do any subdomain tracking at all, then the cookies are set without the leading period. So this leads me to believe that it's a non-issue at least as far as cookie compliance is concerned.

Either way you approach this, you're going to have exceptions:

1. If you default to using the leading period, then anytime you add subdomain tracking on a site that already had Google Analytics implemented, then you'll have to consider how much of a negative impact using the leading period is going to have and possibly not use it.
2. If you default to not using the leading period, then anytime you add subdomain tracking you'll have to make sure/hope there aren't any sub-sub-domains.

For me, I find that the exceptions for #2 crop up far less frequently than for #1. Not only that, handling the exceptions for #2 is pretty cut and dry, whereas handling those for #1 involve much more of a judgment call.

Also, to be perfectly honest, I've always felt more comfortable not using the leading period. It's always felt like the right way to do it. It seems to lead to safer setups. But I can easily see how someone could have started out always using the leading period and so instead they feel more comfortable using, it feels right, it seems safer. So I'm OK with someone taking the #1 approach to it instead, but I'll probably continue taking the #2 approach.

February 10, 2011 12:49 PM

Steffen said:

Hey Jeremy, thanks for your post. Very interesting.

I'm facing the following problem: with a few days gap after deploying your recommended tracking setting, traffic from a referring subdomain drops significantly. Expected effect on _addIgnoredRef(). Meanwhile, direct traffic increases. That - in turn - is not what I expected and in my case not supposed to be. What's the benefit from tracking subdomain traffic as direct traffic? That's even more confusing than tracking as referring. I expected that traffic to become "internal" traffic. How to achieve that?
And why is that gap from ... say 10 days?

Thanks in advance.

February 24, 2011 7:56 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Steffen: I can't determine the exact cause without seeing the code or looking at the site, but if traffic from a subdomain is showing up as direct, then that indicates some type of code inconsistency between the main domain and the subdomain. Here are some things to consider:

1. Are you wanting to track the main domain and the subdomain together? Sometimes people want to track these separately, or they don't want to/can't track the subdomain for some reason and want it tracked as a referring source. This article assumes that you do want to track them together.

2. If you're tracking the main domain and the subdomain together, then the Google Analytics Tracking Code on each should be very similar, if not identical. In particular, the _setDomainName and _setAllowHash statements (or lack thereof) must be identical. You can't have a leading period on one and not on the other, use _setDomainName("none") on one and not on the other, or use _setAllowHash("false") on one and not on the other.

3. Are you running any Google Website Optimizer tests on either the main domain or the subdomain? Similar to #2, the Google Website Optimizer code must have the same set of modifications as your Google Analytics Tracking Code. This is fairly straightforward for the tracking script and conversion script, but the control script needs to be modified using equivalent urchin.js style modifications.

4. Is there any other Google Analytics Tracking Code on any of the pages? This includes legacy code, code put there by someone else for some other purpose, or even UTM code for Urchin. Any extra code like this will need to either be modified to match your Google Analytics Tracking Code or removed.

February 24, 2011 8:20 AM

Cory said:

Hi Jeremy,

This is such a great article. I recently spent a lot of time scratching my head over some self-referrals until we saw this.

I quickly implemented your code as outlined above on a simple (/path/page.aspx) www domain and a developer added matching script on a more complex transaction subdomain(pages.aspx?pid=000 etc)

Unfortunately, I'm able to see only traffic that moves from the "complex" (www) site to the "simple" (subdomain) site but not the other way around.

What do you think that means? On which CMS should I look to edit?

Thank you!

February 24, 2011 1:08 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Cory: My previous comment most likely applies here as well. In particular, you should check both sites for legacy Google Analytics Tracking Code that might have a different set of modifications than the code you just added. The legacy code will then have to either be modified or removed.

February 24, 2011 1:20 PM

Peter O'Neill said:

Hi Jeremy,

Just had a long discussion with an ex-colleague about _addignoredref and want to clarify what the impact of it is.

In point 3 of the blog, you recommend using it to avoid self-referrals when a visit session expires between pageviews. That makes sense but I can't see this causing a high percentage of self-referrals. For most sites, this should occur a minimal number of times. If a site has many visits timing out (maybe due to video), would suggest increasing length of visit.

Instead won't using this code eliminate recording of all self referrals as they will all be reported as the previous referrers or as Direct? As you say in one of the comments, this information can be useful for finding untagged pages or untagged links between subdomains.

Thanks - Peter

March 4, 2011 6:25 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Peter: Pages with a lot of content or videos can certainly exacerbate the issue, but self-referrals will often make up 1 to 2 % or more of traffic even on sites without videos or long sales letters.

I'll speculate on why and say that in general, we often don't have a captive audience on the web. Someone may be on one site, think of something and open up a tab to check something on another site, or maybe they notice they have an email, or maybe they get a phone call, etc. Depending on the type site, they may also be doing comparison shopping and have 10 different tabs open at once.

Regardless of why this is happening, _addIgnoredRef is a nice solution because it only applies to visitors that have previous referral data available. This means that a visitor won't just show up as direct instead of a self-referral, unless of course they were previously direct.

A new visitor who starts at an untagged page and moves to a tagged page will still show up a a self-referral, even if you're using _addIgnoredRef. Eventually this will happen for enough visitors that you'll see the problem in your Google Analytics reports.

This is especially true of untagged landing pages, but a page not designed to be a landing page will usually still end up as a landing page for enough people to point out the problem in Google Analytics. But if you still have the 1 to 2% of noise coming from self-referrals that could have easily been prevented by _addIgnoredRef, it makes it much harder to catch these pages.

Even if self-referrals only showed up for true problems, I'd still use _addIgnoredRef because it's more important to preserve referral information when possible than to fix a problem on a single page. If the page is important enough, then the tagging issue on that page will become obvious at some point anyway, even without a bunch of self-referrals to point it out. If it's not a very important page, then the misfortune of having that page missing from your reports is still outweighed by the benefit of having correct referral information for those visitors who spent a little too long on that page (or the previous page) for whatever reason.

March 4, 2011 7:57 AM

Peter O'Neill said:

Thanks for the detailed reply. I hadn't realised the degree to which self-referrals are driven by visitors timing out - that does change the situation.

I also agree with your logic on using _addIgnoredRef based on how you have described it as working. However that appears to be different to the Google description (which I know is wrong occasionally). They say

Excludes a source as a referring site. Use this option when you want to set certain referring links as direct traffic, rather than as referring sites. For example, your company might own another domain that you want to track as direct traffic so that it does not show up on the "Referring Sites" reports.

This suggests that all traffic from the domain specified will be reported as Direct. As opposed to what you have written which is it will pick up the previous referrer for returning visitors and have no affect on new visitors. Have you found that this is the way it works in practice and that this is another example of where Google needs to update their documentation?

March 4, 2011 12:49 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Peter: Yes, I would say that the Google documentation on _addIgnoredRef is a bit misleading. In practice, it works as I've described it.

March 4, 2011 1:07 PM

Peter O'Neill said:

Ok, that explains my confusion. Thanks for the assistance and the detailed explanations given.

March 4, 2011 1:26 PM

Rene said:

Very useful information and i did understand it until you mentioned crossdomain tracking needing a different approach with:
_gaq.push(['_setAllowHash', false]);
_gaq.push(['_setAllowLinker', true]);

What if you want to track example.com, store.example.com and example2.com together.So this would be Tracking Across Multiple Domains and one Sub-domain.

Would you use the following?

example.com
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-12345-1']);
_gaq.push(['_setDomainName', 'example.com']);
_gaq.push(['_setAllowHash', false]);
_gaq.push(['_setAllowLinker', true]);
_gaq.push(['_addIgnoredRef', 'example.com']);
_gaq.push(['_addIgnoredRef', 'example2.com']);
_gaq.push(['_trackPageview']);

store.example.com
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-12345-1']);
_gaq.push(['_setDomainName', 'example.com']);
_gaq.push(['_setAllowHash', false]);
_gaq.push(['_setAllowLinker', true]);
_gaq.push(['_addIgnoredRef', 'example.com']);
_gaq.push(['_addIgnoredRef', 'example2.com']);
_gaq.push(['_trackPageview']);

example2.com
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-12345-1']);
_gaq.push(['_setDomainName', 'example.com']);
_gaq.push(['_setAllowHash', false]);
_gaq.push(['_setAllowLinker', true]);
_gaq.push(['_addIgnoredRef', 'example.com']);
_gaq.push(['_addIgnoredRef', 'example2.com']);
_gaq.push(['_trackPageview']);

March 15, 2011 5:31 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Rene: The code for example2.com should be a little different:

var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-12345-1']);
_gaq.push(['_setDomainName', 'example2.com']);
_gaq.push(['_setAllowHash', false]);
_gaq.push(['_setAllowLinker', true]);
_gaq.push(['_addIgnoredRef', 'example.com']);
_gaq.push(['_addIgnoredRef', 'example2.com']);
_gaq.push(['_trackPageview']);

It'd important that the _setDomainName call match the root level domain of the site the code is on. If it doesn't match, then no cookies will be set and you won't get any Google Analytics data for those pages.

March 15, 2011 7:51 AM

Jeff said:

What if I want to track all of my subdomains independently? How do I set that up?
Each of my clients will have a branded website for themselves that I am hosting as a subdomain. I need to be able to generate a report showing Client A his traffic without any other clients info in there.
Currently we only have about 8-10 of these clients but the number is growing and could reach into the hundreds.
Any suggestions for this GA challenged guy?
Thanks in advance!
Jeff

March 28, 2011 4:19 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Jeff: See the comment at the end of the this post.

March 28, 2011 5:03 PM

Jeff said:

Thank you! I didn't realize there was a different post and kept looking at this one for a reply.
Thank you again!

March 30, 2011 12:59 AM

anobre said:

Hi there!
I've implemented this tracking code style and it seems to be working great with a catch. Now when i go , for instance, to top content report and click 'visit link' i'am always sent to the top domain when in most cases i should be redirected to a subdomain.

Cheers,

April 14, 2011 3:11 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@anobre: You'll need to add two steps to this:

1. Add a filter to add the hostname to the beginning of the request uri. Usually I use something like this:

Filter type: Custom Filter (Advanced)
Field A: Hostname
Extract A: (.*)
Field B: Request URI
Extract B: (.*)
Output to: Request URI
Constructor: $A1$B1
Field A Required: Yes
Field B Required: Yes
Override Output Field: Yes

2. Edit the Main Website Profile Information and change the Website URL to:

http://

This won't fix the existing data in your profile, but going forward, clicking on a link will go to the correct subdomain. This works for sites with multiple domains as well.

April 14, 2011 3:44 PM

Ryan said:

Hi Jeremy - great post. I was trying to follow along your comment discussion with Rene about cross-domain with sub-domain tracking but believe I missed something.

If I am tracking from www.mainstore.com (or mainstore.com) to 3rd party checkout which is a sub subdomain: checkout.sub.main.net - is what I have correct:


Site (mainstore.com):
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-XXXXX']);
_gaq.push(['_setDomainName', '.mainstore.com']);
_gaq.push(['_setAllowHash', false]);
_gaq.push(['_setAllowLinker', true]);
_gaq.push(['_setAllowAnchor', true]);
_gaq.push(['_addIgnoredRef', 'mainstore.com']);
_gaq.push(['_trackPageview']);


3rd Party (checkout.sub.main.net):

var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-XXXXX']);
_gaq.push(['_setDomainName', '.main.net']);
_gaq.push(['_setAllowHash', false]);
_gaq.push(['_setAllowLinker', true]);
_gaq.push(['_setAllowAnchor', true]);
_gaq.push(['_addIgnoredRef', 'mainstore.com']);
_gaq.push(['_addIgnoredRef', 'main.net']);
_gaq.push(['_trackPageview']);


Does that look correct (assuming the linker tags are in place)?

April 14, 2011 4:30 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Ryan: That code looks fine. The one thing I would add is that the _setDomainName call is optional for the third party domain unless you're tracking across subdomains on the third party domain. That is, if a visitor goes from your site to checkout.sub.main.net and doesn't see any other subdomains on main.net, then there's no need to do subdomain tracking for the third party domain.

Also, if you have two sites, one with sub subdomains and the other without sub subdomains, technically you only have to use the leading period on the site with sub sub domains. So even if a visitor could go from checkout.sub.main.next to somewhere else on main.net, that doesn't mean you need a leading period for mainstore.com as well.

As discussed in the article, you can certainly still include the leading period if you feel strongly about it, but there are benefits to not using the leading period which you might be able to take advantage of. It might also be difficult to remember which sites you have to use it for and which you don't, in which case always using the leading period may make more sense.

April 14, 2011 4:52 PM

Ryan said:

Great, I will try taking out the leading periods. Thank you Jeremy

April 14, 2011 4:55 PM

Brian Moore ? said:

Some thing tells me I ruined/fubar'd my analytics.

ok I have a ecommerce site using a 3rd party shopping cart.

my analytics code is this:
mysite.com

var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-*********-1']);
_gaq.push(['_setDomainName', 'none']);
_gaq.push(['_setAllowLinker', true]);
_gaq.push(['_setAllowHash', false]);

3rd party cart
cart.com

var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-********-1']);
_gaq.push(['_setDomainName', 'none']);
_gaq.push(['_setAllowLinker', true]);
_gaq.push(['_trackPageview', 'insert_page_name']);


ever since i implemented this code change so my boss could get the google adwords conversion tracking working the main site shows up as a referrer and now the ecommerce conversion rate in google analytics has droped to zero.

help please.

April 19, 2011 1:35 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Brian: I don't see a _trackPageview call for the mysite.com analytics call, but you may have just left that off. It's also not necessary to have both _gaq.push(['_setDomainName', 'none']); and _gaq.push(['_setAllowHash', false]); on the mysite.com code. You should probably drop the _setDomainName call.

My best guess is that you probably had some sort of linking in place that is now broken as a result of updating your code to the async version. Without knowing anything else, the easiest way you can probably fix that is to add the following after your Google Analytics Tracking Code:

_gaq.push(function() {
window.pageTracker = _gat._getTrackerByName();
});

You can add this after both your mysite.com code and your 3rd party code, assuming that the 3rd party domain links back to your main domain correctly.

April 19, 2011 2:45 PM

Ryan said:

Hi Jeremy,

Unfortunately I am still getting mostly (direct) transactions in my reporting. About 1/3 do contain the referring keyword so I believe I must be on the right track but am perhaps missing something.

This is with a Yahoo! store and I believe I have to the two links tagged correctly that point to the cross-domain from sunshineyoga.com to checkout:(yahoo.net).

Can I pay you to review at my implementation (via view source) to make sure I have the cross links tagged?

When I run through in WASP it looks like the cookie retains all the data so I'm not quite sure what the issue is.

Thank you!

April 20, 2011 11:01 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Ryan: We no longer offer stand-alone Google Analytics support plans. You should look into using Monitus in order to track Yahoo Store. That is what we always recommend for tracking Yahoo Store.

April 20, 2011 12:20 PM

Ryan said:

Do you have anyone you can refer me to?

Not really interested in having to pay monthly for GA data.

Thanks!

April 20, 2011 2:37 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Ryan: Monitus is the only viable solution for tracking Yahoo Stores. So if you don't want to pay monthly, you'll probably want to look into using something besides the Yahoo Store.

April 20, 2011 3:01 PM

Dan said:

If my sub domains have no reference or relationship to the TLD, would I not get valid results if I treated the sub domain the same as a TLD?
I setup a site in a WP multi site environment so wouldn't I just treat the sub domain the same as a TLD, generate and implement analytics the same way I would for a TLD?
Dan

May 2, 2011 10:34 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Dan: If the subdomain does not refer to the main domain and vice versa, then you do not need to implement subdomain tracking. The standard Google Analytics Tracking Code will work fine for both sites. You can either use separate account numbers (within the same Google Analytics account) to track each domain separately, or use the same one if you want roll-up reporting.

The same goes for multiple domains as well. If you have multiple domains and no domain links to any of the other domains, then there's no need to implement cross-domain tracking. The standard Google Analytics Tracking Code will work fine for all sites. And again, you can track the sites separately or in a roll-up profile (or both).

May 4, 2011 8:03 AM

Eric W said:

Hi Jeremy - great article. I recently added similar code in an attempt to fix self-referrals for our websites. The result was partially successful, they dropped dramatically for April (implemented 3/31).

However, we also experienced a massive unexplained drop in Visits and UV's, while our PV and every other performance metric increased.

Is there any reason that getting rid of self-referrals would lower UV's (or, to phrase properly, improperly having self referrals would have been inflating UV counts?)

Thanks,
Eric

May 9, 2011 9:20 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Eric: Self referrals will usually result in inflated visit counts. Inflated UV counts are less common, but this is also possible depending on what your code looked like before. Unique visitor counts are largely based on the __utma cookie remaining intact. So if your Google Analytics Tracking Code setup results in this cookie being recreated, then you will get an artificial spike in UVs.

May 10, 2011 7:59 AM

Eric W said:

Thank you very much! I was able remove my fix and test it and actually see the Unique Visitor ID change, creating extra UV's. Appreciate your feedback!

May 10, 2011 11:06 AM

Eric said:

Another question for you Jeremy.

Our sites have 1 main domain and 1 main subdomain. We get a ton of self referrals and corrected some of them by adding 1 missing line of code to our main domain pages.

However, we are still getting quite a few.

Here is the code we are using. Is this correct?


var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA of Main Page']);
_gaq.push(['_setDomainName', '.ericsite.com']); (this line was missing and was added 5 weeks ago, fixing about 60% of our self referrals)
_gaq.push(['_trackPageview']);

_gaq.push(['_setAccount', 'UA of rollup account']);
_gaq.push(['_setDomainName', '.ericsite.com']);
_gaq.push(['_trackPageview']);
_gaq.push(['_setAccount', 'UA of another rollup account']);
_gaq.push(['_setDomainName', '.ericsite.com']);
_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);
})();

May 12, 2011 4:30 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Eric: As mentioned in the post you should also add the following line for each account:

_gaq.push(['_addIgnoredRef', 'ericsite.com']);

This line can go right after the _setDomainName line for each account. Also note that I intentionally left out the period in front of ericsite.com. This is correct regardless of whether you use a leading period with _setDomainName or not.

May 12, 2011 4:45 PM

Eric said:

Thanks again, will report back results!

May 12, 2011 9:14 PM

Eric said:

Greetings again -

The addition of that code has had no impact. If we had our sites live for a solid 6 months with a subdomain issue, is it possible/likely that the remaining self-referrals we still see after fixing things are simply "baked" in to cookies and not fixable until the cookie expires?

Very much at a loss now.

Thanks again!
Eric

May 23, 2011 7:46 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Eric: Yes, it may take some time to work itself out. Not only do you have return visitors who already have cookies for self-referrals, but you also potentially have return visitors who are viewing cached pages with the old code that may still have their referral information overwritten with a self-referral.

Also note that this code change doesn't address other fixable sources of self-referral traffic. For example, if you have a landing page that's missing the tracking code altogether, the code change won't fix those self-referrals, but you can still fix the issue by adding the tracking code to that landing page.

May 24, 2011 7:13 AM

Eric said:

Couple more things.

#1 - I've had one site that has been fixed for 3 months now (2/22 fix date). That being the case, I'd expect their remaining self-referrals to be slowly dropping off over time. However, they are staying pretty flat since the initial drop from my 2/22 fix. That concerns me.

#2 - I added the hash setting to the site I tried your suggestion on last week. It now looks like this :
var _gaq = _gaq || [];
_gaq.push(['_setAccount', '']);
_gaq.push(['_setDomainName', '.ericsite.com']);
_gaq.push(['_addIgnoredRef', 'ericsite.com']);
_gaq.push(['_setAllowHash', false]);
_gaq.push(['_trackPageview']);


While the addition of addIgnoredRef last week had no impact on the self-referral count, the addition of setAllowHash false seems to have had a definite impact in lessening the self-referrals.

Does that make any sense to you?

Are there any drawbacks to turning off the hash like that?

Thanks again!
Eric

May 25, 2011 2:02 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Eric: Turning the hash off would cause a cookie reset for all your return visitors. So while this does remove all of the lingering self-referrals, it also removes all of the referral attribution for all of your return visitors. Most likely you're now seeing a jump in direct traffic.

May 26, 2011 7:37 AM

Eric said:

Yep - that's exactly what happening. Direct jumped from 32% to 49%.

Is the cookie reset from turning off hash a 1 time thing?

In other words, if I leave it as is, are the cookies being constantly reset for the same user over and over?

Thank you sooo much for the assistance. Invaluable.

May 26, 2011 1:48 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Eric: The cookies will only be reset a maximum of once per user, and only for users visited the site prior to the code change. For new visitors, the cookies will be set correctly for the first visit and will not be reset for subsequent visits (though of course standard attribution rules apply).

May 26, 2011 3:16 PM

Jonathan said:

Hi Jeremy - fantastic post, I've been looking for a way to fix our self-referral issue for a very long time.

Before I implement the changes you suggest (i.e. add addIgnoredRef) , a quick question about leading periods:

We've been using Google Analytics across multiple subdomains (but no lower level domains) for over a year, and have always used setDomainName with a leading period. I know you generally recommend not to use the leading period when making the "switch" to subdomain tracking, but what would you do in our situation, given that we've already used the leading period in setDomainName for such a long time?

Thanks for your help!
Jonathan

June 1, 2011 12:58 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Jonathan: If you've been using the leading period the whole time, then you're probably better off sticking with it. The main exception would if you've often had cookie corruption due to things like poor Google Website Optimizer implementations. In that case, moving to not using the leading period would still cause an initial cookie reset, but might prevent additional cookie resets down the road.

June 1, 2011 5:31 PM

Doug Gebhardt said:

What an amazing post. Thanks so much Jeremy. Looks like it has kept you hopping! I'm wondering about what happens when www2 is showing up in my referral traffic as the number 1 referrer. Would this help to eliminate this sort of self referral? Here is what we have right now.
var pageTracker = _gat._getTracker("UA-1234567-1");
pageTracker._setDomainName(".sample.ca");
pageTracker._setAllowLinker(true);
pageTracker._setAllowHash(false);
pageTracker._trackPageview();
Based on your other answers here, the leading period should be removed in the setDomainName as well to prevent the subdomains as showing up as referrers.
Cheers!

June 5, 2011 9:44 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Doug: The main reason for leaving off the leading period is that it creates cookies that are compatible with the standard, unmodified Google Analytics Tracking Code on your main domain. If you're using the leading period and already have for a while, then switching will cause a cookie reset. Also, whether or not you use the leading period does not affect whether or not you have self-referrals.

Adding the following line should help with some of the self-referrals:

pageTracker._addIgnoredRef("sample.ca");

As mentioned in the post, the leading period should not be used for this method, regardless of whether or not you use it in your _setDomainName call. This call can go right after _setDomainName call.

It's always possible that there may be some other reason why you're getting self-referrals, but this addresses one source of self-referrals caused by subdomain tracking in general.

June 6, 2011 7:26 AM

Devendra Singh said:

Quite informative post, especially because it even tries to correct some documentation mistakes of GA.

A small query please:
We have couple of websites on subdomains. Each one does its own SEO to attract Search Engine Traffic. The Visitors may land to any of the subdomain websites from Search Engine Referral. Later if the Visitor clicks a link to move to the sister subdomain, we still see the original source as the Referral Site. That's okay. But, is there a way to track that how many referrals were transferred to each other (without event tracking)?

Thanks,

DS

July 3, 2011 12:19 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Devendra: You could probably do this to some extent with custom variables or internal site search tracking. Another option would be to use a second tracking object. This would look something like this:

_gaq.push(['_setAccount', 'UA-XXXXXXX-1']);
_gaq.push(['_setDomainName', 'mydomain.com']);
_gaq.push(['_trackPageview']);

_gaq.push(['t2._setAccount', 'UA-XXXXXXX-2']);
_gaq.push(['t2._setDomainName', document.domain]);
_gaq.push(['t2._trackPageview']);

The idea here is that the first tracking object will have its cookies set to the root level domain, while the second tracking object will have its cookies set to the entire domain, including the subdomain. Some key things to notice:

1. Two separate accounts are used (UA-XXXXXXX-1 and UA-XXXXXXX-2).
2. 'mydomain.com' is a string while document.domain is not
3. This will only work reliably well in single domain with subdomain situations.
4. For the same reason as #3, do not use _gaq.push(['_setAllowHash', false]); even if you see documentation that says that you need to for subdomains.

July 5, 2011 7:45 AM

Ruby said:

Hi Jeremy, thanks for writing the article. It is very useful. I am new to GA. I have few questions about subdomain tracking.

I have a website site with sub.example.com and subsub.sub.example.com. The subsub.sub.example.com is not a brand new site so I should use

_gaq.push(['_setDomainName', '.example.com']);

to allow leading time for the site. With the dot in front of the domain name. Is it correct?

The code below should be in both sub.example.com and subsub.sub.example.com sites:

var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-12345-1']);
_gaq.push(['_setDomainName', '.example.com']);
_gaq.push(['_addIgnoredRef', 'example.com']);
_gaq.push(['_trackPageview']);

Also there is another subdomains under the same domain name, for example abc.example.com and efg.example .com. Will the code above track traffic from the other sub domains as well?

Many thanks

July 13, 2011 9:40 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Ruby: Your code looks correct. Because you have multiple levels of subdomains (e.g. subsub.sub.example.com), the leading period is strictly necessary. The same code works for just one level of subdomains (e.g. abc.example.com). The addIgnoredRef call is also correct; no leading period gives you the best coverage since this is simply a substring match using indexOf.

July 14, 2011 10:52 AM

webzdev said:

Hello Jeremy thnak you very much for your post. It was like hell for me to clarify to myself what is right and what is wrong.

I have following situation:
A year ago I did set up GA on a domain example.com BUT code looks like this:
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-xxxxxx-y']);
_gaq.push(['_setDomainName', '.example.com']);
_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);
})();

now I created a subdomain sub.example.com created a separate Profile in GA dashboard. Now I have 2 profiles for site url example.com. I copied GA code suggested by google, pasted it on sub.** but code looks like tihs:
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-xxxxxx-y']);
_gaq.push(['_setDomainName', '.example.com']);
_gaq.push(['_trackPageview']);
(it is the same as this on my main domain) I notice in dashboard there are different profile IDs but they are not addressed in the GA code.

I am confused what exactly should I do to track my subdomain AS A FULLY INDEPENDENT site.
Should I add sub.example.com as new site so I receive a different code or should I retain the second profile with some adjustments??

July 24, 2011 12:25 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

When you add a new profile, you should select the option to add the profile for a new domain rather than an existing domain. This will give you an account number that's separate from your existing profile. Note, however, that the only difference between the two account numbers will be the "-y" at the very end of the number. This is sufficient to track the sites separately.

Also, since you're tracking this subdomain separately, you may want to consider removing the _setDomainName line, to avoid sharing cookies between this subdomain and your existing site.

July 25, 2011 9:16 AM

Vikas Sahdev ? said:

Hi Jeremy,
You are the recognized GA expert here, so I would ask your advice. In between reading multiple threads, I am sort of confused and want to clarify whether what I am doing is correct.

I have two sites: www.example.com and a subdomain www.blog.example.com

What I want is:

1. Sub domain tracking

2. One GA Profile which tracks both the main domain and sub domain.

3. Conversion funnel from all pages on the www.blog.example.com to www.example.com

This is what I have done so far:


1.
I added the below code to www.example.com and www.blog.example.com:

var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-XXXXXX-1']);
_gaq.push(['_setDomainName', 'example.com']);
_gaq.push(['_addIgnoredRef', 'example.com']);
_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);
})();

2.

Created one Master Profile in GA( for www.example.com) without any filters


3.

Created a duplicate of the Master Profile in GA( for www.example.com) with the subdomain filter described earlier in the thread.


Below are the Questions I have:

1. Does the above set up look correct considering what I want to achieve?
2. It has been a day since I set up the second profile but still don't see any visits. Any ideas if something is wrong?
3. I want to implement a funnel whereby i want to track how many visitors from anywhere on www.blog.example.com came to www.example.com. Both the sites don't have default pages in the url( i.e no www.blog.example.com/default.aspx e.g). So in the funnel, how do i define step1 and step 2 urls since both sites have "/" as their default page?

4. Since both the profiles I have contain data from both sites, how do I "filter" reports for one site vs the other? For e.g I woudl like to know the unique visitors to only the blog site and not the main domain site. Is that possible?


Thanks a ton for your help looking into this.


July 29, 2011 5:32 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

Your best bet is to probably use an advanced filter for visits that include both hostnames. You could set this up as a goal, but it would only be useful if you checked the required step box, and even then only within the Funnel Visualization report. When you have a filter that modifies the request uri, the Goal URL and Funnel Steps should match the modified request uri instead, which means that you can do a head match on blog.example.com and www.example.com. The main thing to check if there's still no data is that the other profile is a duplicate of the other one, that is, the web properties should be the same. It's easy to create another profile that uses a -2 instead of a -1 in its Google Analytics Tracking Code.

August 1, 2011 5:29 PM

Vikas Sahdev ? said:

Thanks Jeremy. I have two more questions from your original article:

1. _gaq.push(['_addIgnoredRef', 'example.com']);

If I put the above line in the GA code, both for root domain and subdomain, would I still see the traffic coming from www.blog.example.com to www.example.com. Since I would like to track conversion from the blog site(sub domain) to main site( root domain), I don't want to loose the referrals from blog site to main site.

What reports exactly get impacted by using the code line above? Is it only the Reffering sites report?


2. _gaq.push(['_setDomainName', 'example.com']);

We had a separate GA ID for the subdomain and root domain and thus separate profiles in GA for each of those and we were using leading period in the setDomainName. This was happening for over a year.

Recently we started using the same GA ID for the subdomain and root domain and one profile for both sites with the cross domain filter applied.

In this situation, do you recommend that we keep the leading period or remove it in the above line of code ?

I am also confused by your original comment in the article which says "What this means is that if you weren't doing subdomain tracking previously".

I am not sure what exactly constitutes "doing subdomain tracking" to be able to say whether that condition applies to us. What I am doing is summarized in the previous post. Does that constitute what you meant by "doing subdomain tracking"?


Thanks again!!

August 9, 2011 7:01 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Vikas: _addIgnoredRef is a soft ignore, that is, it only ignores the referrer if there is pre-existing referral information. For example, if your tracking code is set up so that someone starting on the blog and moving to the main domain is counted as a blog referral, then adding _addIgnoredRef won't change that. If instead someone starts on the main site, moves to the blog, then moves back to the main site, then they will not count as a blog referral, even if they spent more than 30 minutes on the blog, because there were already cookies on the main site.

If you were previously using the leading period with _setDomainName, it's probably best to continue using the leading period unless you've been having problems. For example, if someone keeps setting up GWO tests and they can't remember to add proper subdomain tracking modifications, dropping the leading period might help alleviate some of those issues.

"Doing subdomain tracking" refers to using _setDomainName to share cookies across subdomains, regardless of whether you used the leading period. If you have subdomains, but you're not using _setDomainName, then you're not doing subdomain tracking because each subdomain is more or less being treated as a separate site.

In your scenario, it sounds like you want to be able to see traffic that's referred from the blog. In that case, using any form of _setDomainName doesn't make sense because you don't want the cookies to be shared between the two subdomains. _addIgnoredRef probably isn't a bad idea though since it will only give the blog credit when they came to the blog first. You won't easily be able to tell which keywords that sent visitors to the blog resulted in conversions on the main site, however, since those conversions will be credited to the blog instead of the keyword.

August 10, 2011 7:34 AM

Darius said:

Hi,

I tried this but it doesn't work. It still double counts visits over sub-domains, but now it just comes through as all direct. (I implemented it on a website which gets no traffic - so it was a controlled test).

The implementation suggested on the GA website also doesn't work. It ends up with loads of self-referrals.

August 11, 2011 5:47 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Darius: It's hard to know what the issue is without seeing the site. Normally with something like this I would use a cookie viewer like firebug with firecookie and a headers viewer like httpfox so I can see exactly when the issue occurs. Usually you can just use some fake tags like http://www.example.com/?utm_source=test&utm_medium=test&utm_campaign=test and then see when the cookies change to direct.

It may be that there's some rogue code on the page that doesn't have proper subdomain modifications that's causing the issue. This code could be legacy code that's still on the page, Google Website Optimizer code, or possible urchin Urchin UTM code.

August 11, 2011 7:53 AM

Tauseef said:

Hi Jeremy,

Thanks for the information. I update the code to track sub domain and domain traffic. I have two top level domain mobile.customizedstickers.com
blog.customizedstickers.com

The one I am more want to see not as a referral traffic is mobile cause I get conversion from that (Paid and Organic). After changing the code Now getting traffic as a direct.

Any idea why it's doing it or just a old cookies kicking in.

Any help will be highly appreciable.

Thanks in advance.

Tauseef

August 11, 2011 5:16 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Tauseef: Most likely the direct traffic is return traffic to the site. Because both of your domains are subdomains, the cookies by default would have been at the subdomain level. Now that you've implemented subdomain tracking, cookies will be read and created at the root level domain. This means that you may lose information for returning visitors. Over time, this number should decrease and the percentage of direct traffic should go down.

August 12, 2011 9:43 AM

Owen Smith said:

Hi Jeremy,

Perhaps you can help me out with an issue I'm having.

I have a website like so: mysubdomain.x.x.ca

I store static content (css, js, etc) at: static.mysubdomain.x.x.ca

Now, I don't want cookies to get set on the static subdomain for caching purposes.

On my pages, my tracker looks like :
var _gaq=[
['_setAccount',''],
['_setDomainName', 'mysubdomain.x.x.ca'],
['_trackPageview']
];

However the cookies are still set as ".mysubdomain.x.x.ca"

Can you provide any insight on not including lower-level subdomains?

August 14, 2011 2:54 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Owen: If you explicitly need cookies to not be available for any other domains, then you'll need to use something like this:

_gaq=[
['_setAccount',''],
['_setDomainName', 'none'],
['_trackPageview']
];

Then the cookies will only be available to the domain they were set on. Note that this will also affect the hash, so you need to be careful to check that this works as you expect it to. Also, it might be best not to explicitly set _gaq to an array. _gaq is only temporarily an array; it's later rewritten as an object. So it might not always work as expected.

August 15, 2011 8:05 AM

Ken Holden said:

Would this work for issues regarding a secure subdomain? The site is www.planetdj.com. The user is sent to secure.planetdj.com upon beginning check out. (Feel free to see for yourself).
This is the current code we have implemented.


var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-605157-1']);
_gaq.push(['_setDomainName', 'none']);
_gaq.push(['_setAllowLinker', true]);
_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);
})();

All of our conversions are listed as (direct) / (none).

It's not a referral issue, which is why I ask.

Your help would be awesome. Thanks! Great article!!

August 24, 2011 5:02 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Ken: I would recommend something along these lines:

var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-605157-1']);
_gaq.push(['_setDomainName', 'planetdj.com']);
_gaq.push(['_addIgnoredRef', 'planetdj.com']);
_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);
})();

These modifications will track visitors as they move across subdomains of planetdj.com. As long as everything is on planetdj.com, there's no reason to implement cross domain tracking modifications (_setDomainName('none') or _setAllowHash(false), _setAllowLinker(true), etc.).

August 25, 2011 7:28 AM

Ken Holden said:

Yeah that still didn't work. Would there be interference with the cookies? All our conversion traffic is still labeled as (Direct)/(none).

Care to take a peek? Feel free to start the checkout process, as I feel that's where the issue starts.

August 25, 2011 5:28 PM

HopeThisHelps said:

Note that _setAllowHash() has now been deprecated:

http://code.google.com/apis/analytics/docs/gaJS/gaJSApiDomainDirectory.html#_gat.GA_Tracker_._setAllowHash

and the recommendations on the Google site are now a lot closer to the above. I think they are listening ;-)

September 9, 2011 4:14 AM

David said:

Here is the situation our websites share a main navigation / design thus you can easily navigate between 'www.a.com', 'www.b.com' and 'www.c.com' we also have two subdomains of 'www.a.com' that each website uses for quotes & sales those subdomains are: 'secure.a.com' and 'sale.a.com'.

So if you are on 'www.a.com' and click a main navigation item you could go to 'www.b.com' once there say you add an item to your shopping cart you are take to 'secure.a.com'

Here is the solution we have implemented:

On each domain / subdomain we have placed this code:

_setDomainName is the only thing that changes and reflects the domain or subdomain you are on i.e. in this case ".a.com" on the other domains / subdomains it reads ".b.com", ".c.com", ".secure.a.com" and ".sale.a.com".

var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-XXXXX-1']);
_gaq.push(['_setDomainName', '.a.com']);
_gaq.push(['_setAllowLinker',true]);
_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);
})();

$('a').click(function() {
var url = $(this).attr("href");
if (url)
{
if (url.substring(0, 4) == 'http' && url != '' && url != '#' && url.toLowerCase().indexOf('youtube') {
if (url.substring(0, 4) == 'http')
{
_gaq.push(['_link',url]);
location.href = url;
}
return false;
}
}
});

Here are the questions:

We have noticed a large bump in average time on site, why, and how do we correct this?
Have we setup the code properly for multiple domain tracking & subdomain tracking?

September 16, 2011 10:49 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@David: The code looks reasonable. The _setAllowHash method has been deprecated; it's no longer necessary for cross-domain tracking, but it doesn't hurt much to leave it in. It also looks like you'll potentially be tagging all outbound links, not just the ones to your other domain, but it is easier to implement this way than to check each link against the list of your domains before tagging.

The bump in average time on site makes sense because you're maintaining the session across domains whereas before the session would break as you moved from domain to domain. For example, if you spent 3 minutes on a.com, 3 minutes on b.com, and 3 minutes on c.com, your average time on site in the old model would be 3 minutes, but in the new model it would be 9 minutes.

September 16, 2011 11:27 AM

Nick Budden said:

Hi Jeremy,

Thank you for the great post, I've been search for something like this for quite some time. I'm running a Wordpress network using subdomain installs, and currently all of my sites are being tracked using a single profile. What I hope to accomplish is to have one profile that tracks my primary domain AND my subdomains, and also to have an individual profile associated with each of my individual subdomains. I have a relatively small number of subdomains, and can customize my code for each if needed (i.e. my wordpress users cannot create their own subdomains...the solution does not need to be very dynamic). What would you suggest as the best solution for this?

Again thank you for the article!

October 5, 2011 3:50 PM

Kamran Jamshidi said:

This has been bookmarked, informative and well explained.

Using: _gaq.push(['_addIgnoredRef', 'example-petstore.com']); to filter own things away is useful.

Same goes with search engine reports etc from analytics, you get more clean data using features like:
_gaq.push(['_addIgnoredOrganic', 'www.mydomainname.com']);

October 10, 2011 6:02 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

While it's possible to track everything with a single account number and create the profiles for individual subdomains using filters, it probably makes the most sense to set up a second tracker for each subdomain with a separate account number. The reason is that there are types of hits that cannot be easily excluded using filters, which would show up in all of your profiles unless you took additional measures. This behavior is not well-defined, so you are best off using separate accounts.

Note, however, that these can simply be sub accounts within your main GA account. The profile for your main site might use UA-12345678-1, while the profiles for your subdomains might use UA-12345678-2, UA-12345678-3, etc. Also, the code for each subdomain should probably have the same subdomain modifications as your global tracking code unless you have specific reasons for not doing so. This can help to avoid subtle issues like having global tracking code that includes a leading period on your main site along with tracking code just for the main site that has no subdomain modifications, but in fact includes subdomain tracking that does not use the leading period by default, resulting in a hash conflict.

October 11, 2011 8:04 AM

justin brock said:

Great article, Jeremy.

Google recently updated the subdomain tracking video on Conversion University. In it they advise the leading period. http://services.google.com/analytics/breeze/en/domains_subdomains/index.html

Is your advice still not to use the leading period for those of us who only have subdomains, as opposed to lower-level subdomains?

October 13, 2011 12:20 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Justin: Yes, I still prefer to not use the leading period in situations where there are no lower-level subdomains. Lower-level subdomains are the only situation where a leading period is required. Not including the leading period tends to result in more forgiving tracking code. If someone manages to put up a page without code or the incorrect code, if they launch a website optimizer test, or if they were previously not previously doing subdomain tracking and update their code to include subdomain tracking modifications--all of these situations are handled much better without the leading period.

October 13, 2011 1:35 PM

Dan Lyons said:

Hi Jeremy,

Here's the issue I'm trying to solve:

I have multiple sites with different product catalogues.

SiteA.com - primary site. All shopping cart conversions happen through here. It has multiple subdomains.

SiteB.com - separate domain with no subdomains, has online store. But when an item is "added to cart" on this site, it sends the visitor to SiteA.com to complete the purchase. There is a unique "added to cart" page on SiteA.com that a visitor only sees if they came from SiteB.com - think of it as SiteA.com/cart/SiteBcart-addedtocart. This means anytime we see a pageview of SiteA.com/cart/SiteBcart-addedtocart in the GA reports, it means they were on SiteB and added something into their cart.

We're collecting all data into one profile - this includes SiteA.com and its subdomains and SiteB.com. Code we're using on SiteA.com and its subdomains is as follows:

var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-123456-1']);
_gaq.push(['_setDomainName', 'sitea.com']);
_gaq.push(['_setAllowHash', false]);
_gaq.push(['_setAllowLinker', true]);
_gaq.push(['_trackPageview']);
_gaq.push(['_trackPageLoadTime']);

SiteB.com code:
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-123456-1']);
_gaq.push(['_setDomainName', 'siteb.com']);
_gaq.push(['_setAllowHash', false]);
_gaq.push(['_setAllowLinker', true]);
_gaq.push(['_trackPageview']);
_gaq.push(['_trackPageLoadTime']);

We've tagged all links sending someone from siteb.com to sitea.com with linkbypost.

The issue: while we're tracking visitors successfully on both domains and subdomains, it seems the cookie is getting dropped when an item is placed in the cart on SiteB.com. When I look in the content report and segment down everyone who saw SiteA.com/cart/SiteBcart-addedtocart (visitors I know could only have come from siteb.com to sitea.com after placing an item in their cart) and then use a secondary dimension to identify their source, I'm seeing them as referrals from SiteB.com. I would also expect their landing page to be somewhere on SiteB.com, but landing page is showing up as SiteA.com/cart/SiteBcart-addedtocart.

Would appreciate your thoughts on why the cookie might be getting dropped in this instance.

Thanks!

October 15, 2011 10:42 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Dan: When you tag the links from one domain to the other, the cookie information from the first domain is passed to the second domain through the query string. Oftentimes with carts, these query parameters can become corrupted or may be stripped from the final URL altogether. You would need to confirm that this isn't happening. If it is, then there may be a way to work around it, but it will likely be rather complicated.

October 17, 2011 8:47 AM

ryan said:

Great article. Now for the code you recommend.... Does that go on both the main url and the subdomain? Thanks. Ryan

November 2, 2011 2:10 PM

Kim K said:

If the link to open the subdomain opens in a new window, will that cause a new session to be started? I have the correct codes on the domain and subdomain, but I see that a cookie is being writtem for the subdomain and it doesn't contain the original referrer data. Want to tell my client that they should open the links to the subdomain in the same window. I have never run across this particular "flavor" of setup, although I have coded up dozens and dozens of cross domain tracking setups.

November 23, 2011 2:47 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Kim: Opening the subdomain in a new window should not affect cookies. If cookies are being written improperly, then that means there is some issue with the Google Analytics Tracking Code on the subdomain. Even if the code on the subdomain is correct, it's possible that Google Website Optimizer code, Google Analytics Tracking Code from another vendor, or 3rd party code with built-in Google Analytics Integration might create a second second set of cookies for the subdomain.

November 28, 2011 9:08 AM

Nate said:

Great Post. Quick question. We are tracking multiple subdomains and top level domains on one tag. I noticed a lot of self referrals and came across this post. But have discovered something else. My issue is with the subdomains. One subdomain did not get updated with the GA tag. It had no tag at all. This subdomain is commonly hit when passing between two other subdomains. With this tag being absent, how bad did we mess up our data over that time? So if the users path was as follows (and it always will be):

subdomainA.domain.com > subdomainB.domain.com > subdomainC.domain.com - what did this do to our data?

Obviously we got a referral from subdomainB when, and lost our correct referral information I assume, and did not get page views on subdomainB, but did we also inflate visit count? Did we get a visit when they landed on A and exit when they landed on B and then a new visit when they landed on C?

I know that's a little off topic of this post, but if you have some insight that would be great.

December 15, 2011 2:45 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Nate: In Google Analytics, a session ends when there has been more than 30 minutes between pageviews. When the session ends, this means that the next pageview will result in a new visit and that the referral information of the visitor is subject to being updated. If it's been less than 30 minutes, however, then the referral information will not update unless it's something other than a site referral (i.e. tagged or organic).

This means that you will only get self-referrals when the visitor has spend more than 30 minutes on subdomainB. This also means that whenever the source changes from something else to a self-referral, a new visit has resulted with a new landing page and the visit count has been inflated.

December 15, 2011 3:38 PM

Saul said:

Hi! Thanks for this useful article. I have a one domain and 2 subdomains with your code implementation. But I don't know how track visitors from one subdomain to another..I mean how many new visitors has come to a subdomain and then went to another subdomain for example.

Sorry for my english.

December 23, 2011 6:15 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Saul: This code is for tracking a domain and its subdomains as a single site. When this is implemented, traffic moving from one subdomain to another is not as visible as it would be with the default code. If it's more important for you to see the subdomains as separate sites, then it may be better to just stick with the default code. There are ways to set up two accounts in Google Analytics and track subdomains both ways, as separate sites and as a single site, but this can be tricky to get right. The main concern is that cookies will likely be shared on the main domain unless you make sure to always resolve to www and the account that tracks subdomains individually explicitly sets the domain name to the FQDN (e.g. _gaq.push(['t2._setDomainName', 'www.domain.com']); or _gaq.push(['t2._setDomainName', document.domain]);).

December 27, 2011 10:14 AM

Blanka said:

Hi Jeremy,

the article is great, although I still have troubles with setting the subdomains tracking. We have a big media site with multiple subdomains, but just one parent domain. After customizing the tracking code we got rid of self referrals, but we noticed a huge drop in pageviews, which just doesnt make sense to me. Is there any explanation of why that happens? The code was the following:

_gaq.push(['_setAccount', 'UA-XXXXXXX-1']);
_gaq.push(['_setDomainName', 'mydomain.com']);
_gaq.push(['_trackPageview']);

Thank you!

January 2, 2012 7:31 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Blanka: There shouldn't be a drop in pageviews, so that suggests a configuration issue. One possibility is that the _setDomainName code may be incompatible with some of the subdomains. For example, you might have mydomain.co.uk, or mydomain.someotherdomain.com. Also, if you have multiple levels of subdomains, such as sub1.sub2.mydomain.com, then you'll need to use .mydomain.com instead of mydomain.com. These types of situations all result in no pageviews being generated for the affected subdomain.

January 3, 2012 11:27 AM

Jens said:

Hi Jeremy,

Several days ago I submitted a comment. Since thena couple of other comments have been published, but not mine. Is there a chance my comment ended up in the spam list? I would be really interested to get your feedback on a couple of my questions...

Thanks, Jens

January 3, 2012 7:23 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Jens: I searched for your other comment, but I wasn't able to find it (not even in the spam list). If you wouldn't mind reposting your questions, I would be happy to answer them.

January 4, 2012 8:22 AM

AB said:

This is a very useful post.

A couple of questions:

We were previously using setdomain without a period before the domain name. When we adjusted the GA code for subdomain tracking we then ADDED a period inadvertently.

We noticed that both direct traffic and goal completions increased tremendously.

Is this because users were likely dually cookied and goal completions fired twice?

Thanks,

February 1, 2012 12:41 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@AB: I'm not sure why goal completions would go up, but switching from non-leading period to leading period causes a cookie reset, which results in an increase in direct traffic. Leading period and non-leading period cookies are completely incompatible; each destroys the other.

February 6, 2012 2:55 PM

AB said:

Paid traffic is also showing as direct. Would adding the leading period resolve this issue?

Thanks,

February 7, 2012 10:37 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@AB: Consistency is key. In most cases, it doesn't really matter whether or not you use the leading period, but it does matter that you do the same exact thing on every page of the site. If you have some pages with the leading period and some without, that will seriously affect tracking. Also, any other GA based script on the site needs to be consistent as well. For example, if you're running a GWO test on the site, the same modifications need to be made there as well, including urchin.js style modifications (i.e. _udn = ".example.com";). Sometimes third party scripts will include their own GA tracking, which typically needs to be disabled to avoid interfering with your own code.

Paid Traffic showing up as direct could also be a result of redirects stripping the tags or landing pages with missing or incorrect GA code. For AdWords, you also need to make sure that autotagging is enabled, that your Adwords and Analytics accounts are linked, and that cost data has been applied to all relevant profiles.

February 7, 2012 10:53 AM

Abhijeet Kotwal said:

Hi,

I have a website and a blog which I'm tracking using GA.

We are using following accounts to track the site and the blog (sub domain)

For the main website example.com: UA-1234567-1

For the blog.example.com: UA-1234567-2

The problem is currently, I have to see two separate GA reports and Google is treating Traffic separately.

What I need is, the traffic to the website and blog should be considered as a single source of traffic and
single Report where I can monitor Source, Audience, Content, etc.

P.S. The Website is hosted separately and blog is on WordPress.

Please suggest a solution.

Thanks
Abhijeet

February 9, 2012 4:05 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Abhijeet: You should change the code on the blog so that it uses UA-1234567-1 instead of UA-1234567-2. You'll also need to modify the code on both the blog and the main site for subdomain tracking. Usually this means adding a line of code immediately after the _gaq.push(['_setAccount', 'UA-1234567-1']); line that looks like this:

_gaq.push(['_setDomainName', 'example.com']);

The code may be different depending on the version of GA you have up on the site. If you're using a WordPress plugin for GA, there should be an option to specify the domain as "example.com". I believe it's called "Domain Tracking" under advanced settings.

February 9, 2012 8:48 AM

TW said:

First of all, thank you for this amazingly useful article. Good info is tough to find on this subdomain tracking topic.

My question: I am currently developing a new site (brand new) that will have upwards of 15 subdomains. Since a lot of your advice here deals with those who had previous (no leading period) setups, would you still recommend the no-leading-period setup to me even though I am starting new?

I'm simply trying to figure the best way to track all 15 subdomains in one profile while still able to differentiate between the subdomains in traffic reports.

Any advice is greatly appreciated - thanks!

February 9, 2012 11:56 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@TW: I still prefer no leading period for new setups as long as there aren't multiple levels of subdomains because it gives you a more forgiving setup. For example, a person may set up a Google Website Optimizer test on the site and forget to modify the code for subdomains. If you use the leading period, visitors who get entered into the test will likely have their cookies thoroughly thrashed, leading to invalid data in GA. If your site doesn't use the leading period, then while the GWO setup is not ideal, you have a greater chance of keeping your GA data intact. Similarly, if someone sets up another page or subdomain and forgets to add subdomain modifications to the tracking code, you're more likely to be OK if the rest of your site does not use the leading period than if it does.

As far as differentiating between subdomains in the traffic reports, you can do this for the most part using advanced filters. Advanced filters can let you see all the visits that touched a particular subdomain. It will also include pageviews from other subdomains if they were part of that visit.

If you need to distinguish between subdomains at the pageview level, then I would use an advanced filter to add a prefix to request uri indicating the subdomain. For example, you can set it up so that blog.example.com/index.html will show up in the reports as /blog/index.html. This can be done with a single advanced filter, or with multiple filters if you have longer subdomains that you want to shorten in the page-level reports.

February 9, 2012 12:25 PM

TW said:

Jeremy: Many thanks!

So, to make sure I understand your advice 100%, you're saying:

1) Set up tracking code on all 15 subdomains the same way:

//Tracking code customizations only
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-12345-1']);
_gaq.push(['_setDomainName', 'example-petstore.com']);
_gaq.push(['_addIgnoredRef', 'example-petstore.com']);
_gaq.push(['_trackPageview']);

2) Distinguish between subdomains at the pageview level through advanced filtering / custom reports

If you feel like giving me additional insight into the best way to set up that advanced filter, I'm all ears.

Thanks again!

February 9, 2012 3:55 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@TW: 1. Yes. 2. Advanced Segmentation and standard filters on the profile. The following is one way to set up the filters:

http://code.google.com/apis/analytics/docs/tracking/gaTrackingSite.html#profilesKey

February 10, 2012 8:28 AM

TW said:

Again: Many thanks!

February 10, 2012 2:50 PM

Abhijeet Kotwal said:

Hi,

Thank you very much for the help!

After your feedback I implemented the following code:

var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-1234567-1']);
_gaq.push(['_setDomainName', 'mydomain.com']);
_gaq.push(['_trackPageview']);
_gaq.push(['_setAllowAnchor', true]);

(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);
})();


I implemented this code for mydomain.com and blog.mydomain.com (both hosted seperately)

But after this code implementation the Bounce Rate has drastically jumped from 20%+ to 60%+... For most of the pages on mydomain.com existing pages.

Could you please tell me how do I fix this issue?


Thanks,
Abhijeet

February 13, 2012 11:33 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Abhijeet: Make sure you include _gaq.push(['_addIgnoredRef', 'mydomain.com']); as well. That's not likely the cause of the bounce rate increase, but it's worth adding regardless. It sounds like there may be some rogue code on the site that's no longer compatible with your main tracking code. You can use a tool like httpfox and see if more than one __utm.gif hit is being generated per page. If that doesn't turn anything up, check your browser reports and see if the bounce rate is affecting only one browser. If it's an IE issue, there are IE specific tools you can use to view hits and cookies to try to determine what's going on. If nothing else, it may be worth rolling back the code temporarily until you can determine what's going wrong in a test environment.

February 14, 2012 8:22 AM

Domenico said:

Hi Jeremy,

thanks for this great article.

I have got an issue: I have got an existing main domain (say example.com) which has been collecting data for a couple of years and I now need to set up a third level domain (say something.example.com) within the same UA. I've followed your instructions as far as the third level domain is concerned so the code looks like

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

and set up a brand new profile under Google Analytics with a filter as "Include only traffic from the domains that are equal to something.example.com"

I have modified the tracking on the main domain site as follows

_gaq.push(['_setAccount', 'UA-XXXX-Y']);
_gaq.push(['_setDomainName', 'example.com']);
_gaq.push(['_addIgnoredRef', 'example.com']);
if(condition == true)
{
_gaq.push(['_setCustomVar', 1, 'CustomVarName', CustomVarValue, 2]); // I need this for some special situations
}
_gaq.push(['_trackPageview']);

but the main domain tracking has immediately dropped to 0, while on the second profile has not been collected at all.

What have I done wrong?

Thanks,
Domenico

March 14, 2012 10:53 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Domenico: I don't see anything wrong with the code you've set up. The behavior sounds like there may be an issue with the domain string you're passing to _setDomainName. If this string does not match the root level domain, then your tracking won't work at all. This could be a typo, or perhaps using .net instead of .com or something along those lines. Also note that while with _addIgnoredRef you could pass just 'example' instead of 'example.com' without any ill-effects, the same is not true of _setDomainName.

As far as the filter is concerned, I generally don't trust any of the pre-built filters, but always use a custom filter with the correct regex. In this case, I'd use a custom include filter on the hostname field with a value of "^something\.example\.com$".

March 14, 2012 11:47 AM

Domenico said:

Unfortunately there was no typo and everything seemed correctly set up, at least to me.

I'll give it another try and hope..

Anyway, thanks for your help.
Domenico

March 14, 2012 1:33 PM

Matt said:

Jeremy,

Great post and seriously impressive that you've responded to every commenter! So here's another one: after implementing this code a few months ago I've reduced the amount of self referrers by about 97% BUT I'm still seeing enough to believe that something still needs to be tweaked. First question, can you every totally eliminate self referrers? Second, based on this code do you see any obvious problems or have any suggestions:

I have a www.domain.com and info.domain.com. Code is the same on both:


try { var pageTracker = _gat._getTracker("UA-1234567-1");
pageTracker._setDomainName("domain.com");
pageTracker._trackPageview();
var supplementalTracker = _gat._getTracker('UA-1234567-2'); supplementalTracker._trackPageview();
} catch (err) { }


notice that I'm also pushing data into a second profile as per a client's request. Finally I didn't use addIgnoredRef and if you think that's the solution please let me know.

Thanks

March 30, 2012 11:59 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Matt: I would use _setDomainName("domain.com") for supplementalTracker as well and use _addIgnoredRef("domain.com") for both. That should take care of any lingering self-referral issues.

I think it's possible, but very difficult, to eliminate all self-referrals. If there are a few lingering self-referrals that make up less than 1% of your overall traffic, especially if also less than 1% of key visits (e.g. converting visits), then it's probably not worth chasing down the remaining fraction of a percent. For complex sites, the bar may be higher than 1%.

March 30, 2012 1:01 PM

Matt said:

Thanks Jeremy! Can you provide some reasons why it may be impossible to remove all self-referrals. The only reason I can think of is old cookies from pre-cross domain tracking modification Visitors.

March 30, 2012 2:15 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Matt: That's one reason. Other reasons include cached pages or pages with old/rogue code.

March 30, 2012 3:22 PM

Maggie said:

Hi Jeremy,

Using your article, we recently updated our GA tracking code to the following:
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-111111-1']);
_gaq.push(['_setDomainName', '.domain.com']);
_gaq.push(['_addIgnoredRef', 'domain.com']);
_gaq.push(['_trackPageview']);

Now we need to implement cross-domain tracking as well. Should we just add the _gaq.push(['_setAllowLinker', true]); line, or we should remove the _addIgnoredRef?

April 5, 2012 7:29 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Maggie: Just add the _gaq.push(['_setAllowLinker', true]); line.

April 5, 2012 8:07 AM

Newbie said:

Hi Jeremy,

Thanks for the great article, it's quite a puzzle getting your head around all these settings to be honest. I'm currently reviewing a proposed implementation (below) which requires the referral data between subdomains to be captured in a separate account for each subdomain and the cross domain data to be captured in one overall account. Do you see any reason why this wouldn't work?


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



_gaq.push(['._setAccount', 'UA-xxxxxxx-1']);
_gaq.push(['._setDomainName', '.domain.com']);
_gaq.push(['._trackPageview']);

April 23, 2012 11:39 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

In order for this work, your main domain must resolve all requests to www.domain.com. If it can resolve/does resolve to just domain.com instead, then you will have cookie conflicts for those pages.

I would also recommend using the following instead:

var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-xxxxxxx-1']);
_gaq.push(['_setDomainName', document.domain]);
_gaq.push(['_trackPageview']);



_gaq.push(['._setAccount', 'UA-xxxxxxx-1']);
_gaq.push(['._setDomainName', '.domain.com']);
_gaq.push(['._trackPageview']);

Passing document.domain set cookies to fully qualified domain name without turning off cookie hashing. Passing 'none' also sets cookies to the fully qualified domain name, but it turns off hashing too. The hash allows the the code to determine the correct set of cookies to read from. When it's turned off, the code will read the first set of cookies it finds, which may be the wrong set.

Also, if you don't have any lower-level subdomains (e.g. my.sub.domain.com), and don't expect to have any, then you should use 'domain.com' instead of '.domain.com' This will make your code a bit more resilient if, say, someone puts some rogue code on the site or launches a Google Website Optimizer test.

April 23, 2012 12:19 PM

Jackye said:

Hi Jeremy..
It's so hard to make that works.
We have 2 sub-domains here, and when I put:

_gaq.push(['_setDomainName', '.example-petstore.com']);
_gaq.push(['_setAllowHash', false]);

It get a lot of self referrals. =/
But I didn't understand your suggestion quite sure..
So How can i do it?
Something like that:

_gaq.push(['_setDomainName', 'domain.com']);
_gaq.push(['_addIgnoredRef', 'domain.com']);
_gaq.push(['_trackPageview']);


What will happen with sub1.domain.com and sub2.domain.com? Should I put the same code? Or do I need to put a change on them too?

Thank you so much, these settings are so hard to understand =/

April 26, 2012 4:09 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Jackye: Yes, the code you posted should work:

_gaq.push(['_setDomainName', 'domain.com']);
_gaq.push(['_addIgnoredRef', 'domain.com']);
_gaq.push(['_trackPageview']);

You would use this same code on both sub1.domain.com and sub2.domain.com.

April 26, 2012 4:55 PM

Jackye said:

Thanks!

Another quick one:

Is there any really difference between this:

_gaq.push(['_setDomainName', '.domain.com']);
_gaq.push(['_addIgnoredRef', '.domain.com']);
_gaq.push(['_trackPageview']);

and this:

_gaq.push(['_setDomainName', 'domain.com']);
_gaq.push(['_addIgnoredRef', 'domain.com']);
_gaq.push(['_trackPageview']);

the "." before domain.com really matters?
our domain here is www.domain.com with subdomains: sub1.domain.com and sub2.domain.com

Thanks again!

April 27, 2012 8:51 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Jackye: Yes, there is a difference. If you use the leading period (the "." before domain.com), then your cookies will be set in such a way that they'll be accessible to lower level subdomains (e.g. lowersub1.sub1.domain.com). Most people do not have lower level subdomains, so this is usually unnecessary. Furthermore, cookies set without the leading period are more compatible with cookies set without any subdomain at all.

So if you have the option to not use the leading period, this is usually the way to go as it makes your code more resilient. For example, someone might launch a Google Website Optimizer test on the page without adding subdomain code, or you might use a 3rd party plugin that also happens to have Google Analytics tracking enable. With these types of situations, there's a greater chance that your tracking will be just fine if you don't use the leading period. Otherwise, both of these scenarios would result in a cookie conflict, with the end result being that your cookies would be destroyed and recreated with incorrect referral information.

For _addIgnoredRef, you should not use the leading period regardless of whether or not you use the leading period for _setDomainName. _addIgnoredRef does a straightforward string comparison between the current domain and the string you pass to it. So if someone can get to, say, domain.com without the www, then _addIgnoredRef won't catch it if it has the leading period. You can, in fact, simplify _addIgnored ref and just pass "domain" if you felt like it. Of course, this would potentially ignore domain.org or domain.net as well, but it's really just to illustrate the fact that _addIgnoredRef just checks to see if the string passed to it is a substring of the current domain.

April 27, 2012 9:35 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Jackye: Yes, there is a difference. If you use the leading period (the "." before domain.com), then your cookies will be set in such a way that they'll be accessible to lower level subdomains (e.g. lowersub1.sub1.domain.com). Most people do not have lower level subdomains, so this is usually unnecessary. Furthermore, cookies set without the leading period are more compatible with cookies set without any subdomain at all.

So if you have the option to not use the leading period, this is usually the way to go as it makes your code more resilient. For example, someone might launch a Google Website Optimizer test on the page without adding subdomain code, or you might use a 3rd party plugin that also happens to have Google Analytics tracking enable. With these types of situations, there's a greater chance that your tracking will be just fine if you don't use the leading period. Otherwise, both of these scenarios would result in a cookie conflict, with the end result being that your cookies would be destroyed and recreated with incorrect referral information.

For _addIgnoredRef, you should not use the leading period regardless of whether or not you use the leading period for _setDomainName. _addIgnoredRef does a straightforward string comparison between the current domain and the string you pass to it. So if someone can get to, say, domain.com without the www, then _addIgnoredRef won't catch it if it has the leading period. You can, in fact, simplify _addIgnored ref and just pass "domain" if you felt like it. Of course, this would potentially ignore domain.org or domain.net as well, but it's really just to illustrate the fact that _addIgnoredRef just checks to see if the string passed to it is a substring of the current domain.

April 27, 2012 9:35 AM

Rita said:

I'm trying to understand this (eek) and set up my GA. I have a .com site such as: www.bookstore.com and on that same domain have added www.bookstore.com/blog. (wordpress) What I don't understand is; is the blog considered the subdomain? And would I put the .com site as the domain and leave the blog as the subdomain? Or would I put the .com/blog and leave the main .com as the subdomain ? Then, what exact code would I add to the generated code so that it would all track properly ? Thanks for keeping it simple. :)

June 1, 2012 12:44 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Rita: What you have is a subdirectory. There's no special code needed in order to track your subdirectory in addition to your main site. The standard GA code should work fine.

If your wordpress blog was on blog.bookstore.com, instead of www.bookstore.com/blog, then you would have a subdomain and would need to modify your code.

June 1, 2012 1:21 PM

Rita said:

@Jeremy, okay my website is a eg. www.bookstore.com and my blog is www.bookstore.com/blog so you said that would make it a subdirectory and no need to update the code. Good. So, my question is; what do I put in the profile settings URL and the property settings URL would I only ever need to put eg; www.bookstore.com and then the .com/blog part would automatically pick up in the stats ? So, should property and profile URL's match ? That is what I need to know to finish signing up with my proper settings. Thanks so much!

June 3, 2012 1:22 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

GA does not consider a subdirectory to be a separate site, even if the hosting for that subdirectory is different for the rest of your site. It will pick up on your subdirectory automatically. If you decide to create a profile that only reports on your blog subdirectory, you will need to add a filter to that new profile to only include traffic to that subdirectory. The profile name should probably include the subdirectory as well, only to be able to distinguish it from your main profile, but the subdirectory does not need to be included as part of the URL, and you should not create a new web property for the subdirectory, but rather use the existing web property for your main site.

June 4, 2012 8:50 AM

Nathan Arthur said:

Hello, Jeremy!

I've got a question for you: Will subdomain tracking work when the main domain and the subdomain use different versions of the GA tracking code? I'm using an eCommerce service (store.mydomain.com) which uses legacy ga tracking code, whereas my main site (mydomain.com) uses the new asynchronous version.

The problem I'm trying to fix is that any traffic that came from my main site, to the store, and then ended in a purchase, shows as direct traffic. The original referral data isn't being preserved.

My modified code looks like this:

mydomain.com/.org code:

var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-xxxxxxx-y']);
_gaq.push(['_setDomainName', 'mydomain.com']);
_gaq.push(['_addIgnoredRef', 'mydomain.com']);
_gaq.push(['_addIgnoredRef', 'mydomain.org']);
_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);
})();

store.mydomain.com code:

var pageTracker = _gat._getTracker('UA-xxxxxxx-y');
pageTracker._addDevId('o5cUG');
pageTracker._setAllowLinker(true);
pageTracker._setDomainName('none');
try{pageTracker._setDomainName('mydomain.com');
pageTracker._addIgnoredRef('mydomain.com');
pageTracker._addIgnoredRef('mydomain.org');}catch(e){};
pageTracker._trackPageview();

What am I doing wrong?

June 14, 2012 2:21 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Nathan: You can use different versions of the GA tracking code on different pages. The issue you're having is that visitors are going from a .org site to a .com site. This is a cross-domain situation, which means that you'll need to modify your code for cross domain tracking:

https://developers.google.com/analytics/devguides/collection/gajs/gaTrackingSite

More specifically, you should not have both _setDomainName('none') and _setDomainName('mydomain.com'). I would use the latter on both mydomain.com and store.mydomain.com, and use _setDomainName('mydomain.org') on mydomain.org. You should also include _setAllowLinker('true') on all three sites and make sure to use _link or _linkByPost as appropriate on any links or forms that go from .org to .com or vice versa.

June 15, 2012 8:30 AM

Nathan Arthur said:

Thank you so much for the reply!

So .org is just an alias of our .com address. Anything available on the .com is available on the .org. Is there a way to make Google Analytics play nice with this, and not have to worry about tracking then like they were two different sites? Would using only "_setDomainName('mydomain.com');" achieve that?

I would really like to avoid having to worry about cross-domain tracking if at all possible. We've even thrown around the idea of just setting up a site-wide 301 redirect from .org to .com if it would take the cross-domain aspect out of the picture. I'd rather not have to resort to that, though.

June 18, 2012 8:59 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Nathan: 301 redirecting from .org to .com would avoid the cross-domain situation. Alternatively, you could also have a store.mydomain.org in addition to store.mydomain.com. Then you would just need to be consistent with your links and maintain separate tracking codes for the .org and .com sites, since the _setDomainName line would be different for the .org and the .com sites.

There are also scripts which can be used to tag all of the links going between the two domains. It's still considered cross-domain, but it can take some of the pain out of the setup. It's also not too hard to write your own script, especially if you already have a JavaScript library like jQuery on the site. The trickest part is getting such scripts to work for edge cases such as links and forms with multiple redirects and things like that. If you have full control over all sites, then you may be able to eliminate those types of situations if any exist, which can greatly simplify cross-domain tracking.

June 19, 2012 8:06 AM

Stuti said:

Thank you so much for this.
Made my day
God bless you :)

July 30, 2012 1:55 PM

vincent said:

hi Jeremy:

i have also encounted the self-referral issue, and should it add the the modify code "_gaq.push(['_addIgnoredRef', 'sister-site.com']);" to all pages in each subdomain? or add only one statement in the front page

November 2, 2012 11:16 PM

vincent said:

hi jeremy

i also have the self-referral issue, and i followed your instrcution adding the modified code :"_gaq.push(['_addIgnoredRef', 'sister-site.com']);"
in each pages of our maindomain. but the problem still exist.

should i add the modified code for each pages under each subdomain? or just add only a statement on the front page of our main domain?

as u menetioned in our article :"This also eliminates the need to add a separate _addIgnoredRef statement for each subdomain."

so confused..

November 3, 2012 12:00 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@vincent: You should add the same modification to all subdomains as well.

There is a common misconception that you need to add a separate _addIgnoredRef statement for each subdomain:

// BAD EXAMPLE
_gaq.push(['_addIgnoredRef', 'www.sister-site.com']);
_gaq.push(['_addIgnoredRef', 'blog.sister-site.com']);
_gaq.push(['_addIgnoredRef', 'shop.sister-site.com']);

Instead, only one line is necessary site-wide, regardless of how many subdomains you have:

// GOOD EXAMPLE
_gaq.push(['_addIgnoredRef', 'sister-site.com']);

Note also that the official documentation still recommends:

// BAD EXAMPLE
_gaq.push(['_addIgnoredRef', 'www.sister-site.com']);

which is still wrong since it won't match requests for your domain without the 'www', nor for subdomains.

November 5, 2012 7:55 AM

Jasmina said:

Hello

I want to track www.example.com and not other subdomains, e.g. static.example.com. To that effect I've tried setting _gaq.push(['_setDomainName', 'www.example.com']); but this is not working out as the cookie is still set to example.com so it's also set for static.example.com

How would you recommend that this is implemented so that the cookie is only set for www.example.com and not for static.example.com or any other subdomain?

301 redirect is in place for example.com to www.example.com

November 7, 2012 6:23 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Jasmina: The line you're adding should work, so if you're having trouble with it, make sure you're adding it after the _setAccount line but before the _trackPageview line.

November 8, 2012 7:51 AM

Jasmina said:

Ta Jeremy, it became obvious as soon as I read your comment.

November 8, 2012 4:27 PM

Poulpator said:

Hi,
I have more than 200 subdomain.
And a need to know each unique visitor per subdomain.
Is there a way to view data per subdomain without creating a profile for each subdomain?

Regards from French Alps

November 20, 2012 11:36 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Poulpator: You can set up a custom report with Hostname as a dimension and unique visitors as a metric.

November 20, 2012 3:29 PM

Chris Eldredge said:

are any recommendations in this article now out of date?

thanks for the great article!

May 21, 2013 4:34 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

The code modifications recommended by this article for subdomain tracking are still up to date for ga.js.

May 22, 2013 8:09 AM

Pavel said:

Jeremy, sorry if this has already been answered before, but I couldn't find it in the 3 years of comments to this topic, so would appreciate if you could help me out.
We have a website with 3 language versions.
www.website.com for english
lang1.website.com for lang 1
lang2.website.com for lang 2

Currently we have a default tracking code installed which results in inflated visits, recorded under Referral section of google analytics.

Do we understand this correctly that adding
_gaq.push(['_addIgnoredRef', 'website.com']);
would eliminate those self-referrals?

So if originally the user came from Google to a www-version and then switched to lang1., then with the updated tracking code, Google Analytics would report that visit as a single visit originating from Google but would include two Domain Names under this visit which were visited by the user.

Hmmm, but then, that would be two visits, no?

Do you know, how would such a visit be reflected in the GA-report?

December 6, 2013 12:03 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Pavel: Assuming you're still using ga.js analytics, you will need both lines:

_gaq.push(['_setDomainName', 'website.com']);
_gaq.push(['_addIgnoredRef', 'website.com']);

December 9, 2013 12:42 PM

anna-lisa said:

Hi Jeremy, thanks for your helpful post. I have a question: I have a cross domain & subdomain issue, site A with subdomain A1/A2/A3 and so on, and the conversion/transaction occurs on Site B. I have set a duplicated complete profile for all visits to site A with a filter which includes all visits coming from subdomains. Then I have set single profiles for each subdomain with a filter including visits from each subdomain (filter Host name). On these single profiles I can't see any conversion/transaction. I presume it's because the filter includes only visits from subdomain, so visits (and conversions) from Site B are excluded.

Am I right? Is there a way to solve this problem?

February 28, 2014 5:38 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

If you track all of the domains and sub domains in a single view/profile, then you should be able to create custom advanced segments for each subdomain. Any filter solution would likely require a complicated set of 3 filters based on an indicator on Site B that lets you know which sub domain it's currently being used for.

March 3, 2014 9:04 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

If you track all of the domains and sub domains in a single view/profile, then you should be able to create custom advanced segments for each subdomain. Any filter solution would likely require a complicated set of 3 filters based on an indicator on Site B that lets you know which sub domain it's currently being used for.

March 3, 2014 9:04 AM

Damion said:

Brilliant! I just wish this post was written..... er, the last time I needed to have this as a reference! I had to cobble together a fix from those various inadequate, outdated, fuzzy articles you mention.

I've bookmarked this, and hopefully I'll remember its existence next time the sound of dying tracking is all around. Devs all too often give little thought to how tracking might be affected by their "quirky" subdomain (or even multi-domain) structure, and I'm hoping that this article might be able to solve a few problems before they spiral out of control. Thanks once again!

January 5, 2011 5:13 PM

Eric Polatty said:

If you go to the tracking code section under profile settings in your GA account, and click "one domain with multiple subodmains" under "what are you tracking", I notice the code Google generates for you to use does not include the _setAllowHash tag. But they tell you to include it in the Google Code article for subdomain tracking. I understand it's a free product - but I find Google's inability to make up their minds about how to use their own software frustrating to say the least.

January 6, 2011 9:51 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Eric: My guess is that the Google Code example includes _setAllowHash because it is on a page dedicated to cross-domain tracking. Unfortunately there's currently no Google Code page that just deals with subdomain tracking. I think we lost this during the transition from the traditional ga.js code to the async code, but I'm hopeful that this will be addressed.

The code that's generated from your Google Analytics account is better, but still suffers from the other issues I went over. The lack of an _addIgnoredRef line, or rather the lack of the logic behind the _addIgnoredRef line being executed for an appropriate _setDomainName call, is especially disconcerting since it implies that _setDomainName is sufficient for optimum subdomain tracking.

January 6, 2011 10:37 AM

Eric Polatty said:

@Jeremy - Most of the main Google Code article is on cross-domain situations, but there is a section "tracking across a domain and it's sudomains" and it has the _setAllowHash tag there.

January 7, 2011 10:26 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Eric: It's possible that since it was sandwiched between the other cross-domain examples that the _setAllowHash tag was added unintentionally. Regardless, it shouldn't be there for a subdomain only example.

January 7, 2011 10:32 AM

Mike Sullivan said:

Thank you! Thank you! Thank you!

We added (yet another) subdomain to our environment over the holidays and I tried (yet again) to get rid of the self-referrals. There's so much not-quite-right guidance out there!

Made your suggested changes and today, they have dropped WAY off!

January 7, 2011 11:50 AM

Adam said:

Great article. I'd just about given up on solving the self referrals issue.

Question: if your site uses both subdomains and lower level subdomains, should you use a leading period on both, or just your lower level subdomain pages?

January 7, 2011 12:05 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Adam: If your site has lower level subdomains, then you should use the leading period site-wide.

If you used the leading period on some subdomains and not on others, the hash codes for the cookies would be different, so your cookies would get destroyed every time you crossed from a page using the leading period to a page not using the leading period and vice versa. So regardless of whether you decide/need to use the leading period or not, you want to be consistent.

January 7, 2011 2:09 PM

david said:

Hi Jeremy,

This article of yours was definitely a nice reading.

I experienced myself lots of issues a few weeks ago when adding subdomain tracking to our site, following Google instructions. One of the main problems was a huge boost of direct traffic (we were using leading period, but we didnt use SetAllowHash).

I am willing to try your solution now. However, would you still recommend this implementation (no period and AddIgnoreRef) even for the traditional ga.js code?

January 10, 2011 7:20 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@David: Yes, I would recommend this solution even if you're using the traditional ga.js code. This would look something like the following:

var pageTracker = _gat._getTracker("UA-12345-1");
pageTracker._setDomainName("example-petstore.com");
pageTracker._addIgnoredRef("example-petstore.com");
pageTracker._trackPageview();

A sudden influx of direct traffic can result from going from no subdomain tracking to subdomain tracking with the leading period. Removing the leading period may help, but this depends on how long you've had the code with the leading period up. There aren't any hard or fast rules on this, but I would say that if you've only had the code with the leading period up for a month or more, you might be better off sticking with it at this point.

There's nothing inherently wrong with using the leading period. The main issue I have with it is that for a site that the hash code generated when you use the leading period is different than the one generated when you don't have subdomain tracking at all. If you've already been using the leading period for a significant amount of time, then switching your code to not use the leading period may be just as bad for tracking as switching to using the leading period in the first place.

Also, for a brand new Google Analytics installation, using the leading period is perfectly fine.

January 10, 2011 8:02 AM

David said:

Thanks for your advice, Jeremy. I will keep your considerations in mind and try your proposed subdomain tracking code.

We had the code with the leading period for just a couple of days. The breakage of the data was big enough to get quickly back to the older version, even though it was not taking into account the existing subdomains.

Hopefully I will get a chance to try your suggestions some day next week. Our site has a large amount of traffic, so after a few hours we will be ready to say if it is working or not. I will let you know ;)

January 10, 2011 10:19 AM

Cloga said:

Excellence article!Thank you!

January 10, 2011 10:46 AM

Cristina Chetroi said:

Hi Jeremy!
The _addIgnoredRef tip to minimise self-referrals is great, as they really are a pain. Thanks!

I also remember someone mentioning the inconsistency between the code GA console generates for subdomain tracking (no setAllowHash to false) and the official documentation.

We all wish domain hashing needn't be compromised. But the reality is that it often is - it's common that a client decides to introduce subdomains or other domains at a later stage and you need to tweak the snippet as the result.

So, when it happens, would it be possible to introduce some sort of cookie checkup for returning visitors and do some sort of merge instead of setting a second set cookies/destroying them?

January 12, 2011 5:19 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Cristina: It would certainly be possible to do that. I've done something similar to that before with cookies that were generated with _setNamespace, so it shouldn't be that hard. I have some other ideas about how this might be done as well, something I'm hoping to write about in a future post.

January 13, 2011 7:54 AM

Liz said:

would i use this customization on all subdomains and the top level domains? Or just all the subdomains I want to track - I will have about 4 or 5 of them.

Thanks

January 27, 2011 2:27 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Liz: I would recommend using the modification on all subdomains and top level domains. I have seen some cases where people wanted to track certain subdomains only so they could see traffic coming from other subdomains as referrals, but this is not an ideal setup. Inevitably someone also wants to track the other subdomains, which gives you strange mix of referrals from subdomains and original referral data to those subdomains showing up in your reports. Instead, you should track everything and use filters in Google Analytics to exclude the unwanted domains.

January 27, 2011 4:26 PM

Bernd said:

You wrote:
_gaq.push(['_setDomainName', 'example-petstore.com']);

Google says:
_gaq.push(['_setDomainName', '.example-petstore.com']);

(see the dot before domainname).

What is the difference?

January 30, 2011 2:16 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Bernd: The main differences are that:

1. Each generates a different hash, but not including a leading period has the same hash as no subdomain tracking at all.
2. Including a leading period works for sites with lower level subdomains (ex. buy.store.example-petstore.com).

Google includes the leading period to account for #2. The reason I don't include the leading period is because of #1. It feel that it's more likely that someone is transitioning their code from no subdomain tracking to subdomain tracking than that they have lower level subdomains.

So, as mentioned in the article, if you have lower level subdomains, or if you're setting up Google Analytics Tracking Code on your site for the first time, use the leading period. If you don't have lower level subdomains and you've had Google Analytics Tracking Code on your site for a while, then don't use the leading period.

January 31, 2011 7:54 AM

Bernd said:

OK, thank you very much, Jeremy!

January 31, 2011 1:33 PM

Nick said:

I'm a little confused. Your second point says that you have to use the leading period if you have lower level subdomains, but then at the end you said don't use if you don't have to.

Let's say I have example.com and store.example.com, would I want to use the leading period to track this properly?

January 31, 2011 5:52 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Nick: The only time you have to use the leading period is if you have lower level subdomains. For your example, the leading period is unnecessary for tracking this properly because you don't have any lower level subdomains. You'd have to have another level of subdomain tacked on to there, such as buy.store.example.com.

If you don't have lower level subdomains and you're setting up Google Analytics for the first time on a site, then you have the option to either use or not use the leading period. I tend to not use it as this tends to be more stable, again because the hash code is the same as if you didn't have subdomain tracking on the main domain. So if someone else sets up a Google Website Optimizer test on your homepage, for example, and forgets to add subdomain tracking modifications, this isn't as big of a deal if you had implemented subdomain tracking without the leading period.

The main benefit to using the leading period for new sites without lower level subdomains is that you'll have less people question your setup since it's closer to the Google recommendations.

For sites with existing Google Analytics Tracking Code that you want to update to use subdomain tracking code, not using the leading period will lead to a much smoother transition. Of course, if your site also has lower level subdomain, you'll have to bite the bullet and use the leading period anyway.

Whichever way you decide to go, make sure that you apply that decision consistently across your site. Having some pages that use the leading period and some that don't will wreak havoc on your site.

February 1, 2011 7:56 AM

Chris said:

I'm working on a WordPress MultiSite project which uses subdomain, some of which are mapped to other domains. So what I'm doing really is more in line with the Google example since its not just sub-domain tracking but cross-domain tracking. My question to you is is there any benefit to using _addIgnoredRef for cross-domain tracking? Or could it hurt in any way? I'm looking to reduce self referals as much as possible.

February 4, 2011 12:21 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Chris: Using _addIgnoredRef will still help some with preventing self-referrals. You should have one _addIgnoredRef statement for each root level domain. _addIgnoredRef only ignores a referral if there is previous referral data to fall back on.

So if you have any links between domains that aren't tagged with the proper linking parameters, this will show up in your reports as self-referrals, even if you use _addIgnoredRef. This is a good thing, because it provides visibility for fixable self-referrals.

If there is previous referral data, however, _addIgnoredRef will preserve it. This can be especially useful in situations where you can tag links to a third-party domain, but have trouble tagging links going back to the original domain.

February 4, 2011 8:33 AM

Rob said:

I tried using Google's subdomain tracking suggestion to no avail. For 1 day I did see in GA URL's from the subdomain but I have not been able to figure out how. I came upon this blog after discussing this with a GA expert who has been gracious enough to help us try a few options.

So I adjusted the subdomain code to look like this, per your suggestions:

var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-xxxxxxx-y']);
_gaq.push(['_setDomainName', 'cae-nyc.org']);
_gaq.push(['_addIgnoredRef', 'cae-nyc.org']);
_gaq.push(['_trackPageview']);


The primary/main Drupal-driven domain has this:


var _gaq = _gaq || [];
_gaq.push(["_setAccount", "UA-xxxxxxx-y"]);
_gaq.push(['_setDomainName', 'cae-nyc.org']);
_gaq.push(['_addIgnoredRef', 'cae-nyc.org']);
_gaq.push(["_trackPageview"]);

Now, a thing to note: we have 2 URL's that we use, hosted on a share GoDaddy account: caenyc.org and cae-nyc.org. (Notice a hyphen). The subdomain does NOT have a hyphen it' all advocacy.caenyc.org. I do not have access to an Apache httpd.conf file so I have to use GoDaddy's GUI/Total Domain Control to create the redirect. Could that be causing the problem? Can you peak at both domains & view their source?

Thanks!

Rob

February 8, 2011 9:44 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Rob: Your code should be different depending on which domain it's on. So on cae-nyc.org (with the hyphen), your code should look like the following:

var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-xxxxxxx-y']);
_gaq.push(['_setDomainName', 'cae-nyc.org']);
_gaq.push(['_addIgnoredRef', 'cae-nyc.org']);
_gaq.push(['_trackPageview']);

But on caenyc.org (without the hyphen), your code should look like the following:

var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-xxxxxxx-y']);
_gaq.push(['_setDomainName', 'caenyc.org']);
_gaq.push(['_addIgnoredRef', 'caenyc.org']);
_gaq.push(['_trackPageview']);

The value you pass to _setDomainName must match the domain it's on, otherwise the code will fail. This is also true when you're tracking both example.com and example.net.

I also don't know if visitors can go back and forth between cae-nyc.org and caenyc.org. If they can, then that falls under the realm of cross-domain tracking, which requires a completely different set of tracking code modifications. Still, you'll need to fix the _setDomainName line on caenyc.org to get any kind of tracking there at all.

February 8, 2011 1:03 PM

Rob said:

Sigh, I wish I had tried the obvious yep that worked. And yes people can go from the sub-domain to the main domain and vice verse.

So for example, an email campaign might start with the sub-domain. Then a person fills out the form on the sub-domain, and clicks on Home, which goes back to the main www domain.

Or, people will click on a link from www, e.g., on the home page, and go to the sub-domain, fill out the form, and may hit home. Does that mean cross-domain?

Also, using the sub-domain filter, the Content report is showing the paths with a leading / like this:

/advocacy.caenyc.org/site/apps/kb/cs/contactsearch.asp

or

/advocacy.caenyc.org/site/c.rwL4JlO7KzE/b.6421085/k.DF6F/Petition_to_Incoming_Schools_Chancellor_Cathie_Black/apps/ka/ct/contactus.asp?c=rwL4JlO7KzE&b=6421085&en=ftINKXMILiKPJ5PUJeILI3OLInKZI7OKJgIXK6OQKtK9F


I take it I can transform the URL with another filter?

February 8, 2011 4:53 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Rob: You only need to implement cross-domain tracking if a visitor can move across root level domains. Going from avocacy.caenyc.org to www.caenyc.org does not count as cross-domain because you're just moving from one subdomain of caenyc.org to another.

Going from avocacy.caenyc.org to www.cae-nyc.org, however, does count as cross-domain tracking and requires additional modifications to your code, as well as modifications to the links going between domains. Generally it's something to be avoided if at all possible.

In your situation, the easiest way to avoid the issue is to just 301 redirect visitors who request cae-nyc.org pages to the appropriate caenyc.org page. This eliminates the need for cross-domain tracking and dramatically simplifies your Google Analytics setup.

With regard to filters, yes, you can apply additional filters after the subdomain filter. Those filters will be applied to the modified URL instead of the original URL, so you can use this to change the URL to look exactly how you want it to in Google Analytics. Also, you may want to look at Exclude URL Query Parameters under the Main Website Profile Information to remove any unnecessary query parameters and clean up reporting even further. This is usually easier than using filters to remove the query parameters.

February 9, 2011 7:57 AM

Emily said:

I have multiple domains that I have the same UA# (cookmedical.com, cookbiodesign.com and cookartlab.com). These domains feed traffic between each other and so it would be helpful if I could track them as if they were all the same site to track users between the domains. Based on this information it sounds like I should add the following to all of the pages in all the domains:

_gaq.push(['_setDomainName', 'none']);
_gaq.push(['_addIgnoredRef', 'cookmedical.com']);
_gaq.push(['_addIgnoredRef', 'cookbiodesign.com']);
_gaq.push(['_addIgnoredRef', 'cookartlab.com']);

Am I understanding you correctly?

February 9, 2011 8:48 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Emily: The _addIgnoredRef lines may help with some self-referrals issues, but they're not directly related to cross-domain tracking.

Cross-domain tracking in Google Analytics is the sort of thing that really deserves a series of posts, but I'll try to summarize it as best as I can within this comment.

First, I generally avoid using _gaq.push(['_setDomainName', 'none']); because it does too much. _gaq.push(['_setAllowHash', false]); (no quotes around false) accomplishes the minimum for cross-domain tracking, so it's preferred.

Second, you'll also need to add _gaq.push(['_setAllowLinker', true]); (again, no quotes around true).

Third, you'll need to modify the links between domains. The easiest way to do this is to have the following onclick attribute in the link:

onclick="_gaq.push(['_link', this.href]); return false;"

This covers most scenarios, but not all of them. There will likely be additional nuances that these instructions won't handle. The official Google Code article may help with some of these.

Here are some other things to keep in mind:

1. _link invokes a javascript redirect, which means the referrer won't be available on the receiving page in IE. There are other ways to do this that preserve the referrer, but they are more advanced.
2. _linkByPost may work with forms that use GET instead of POST, but you'll have to specifiy true in the third parameter, that is:

_gaq.push(['_linkByPost', this, true]);

This passes query parameters through the anchor text instead of the query string. This means you'll also need to add _gaq.push(['_setAllowAnchor', true]); to your Google Analytics Tracking Code.
3. It's generally preferred to accomplish linking between domains in a more dynamic way. You might be able to build this into a template driven site, or use a script that modifies onclick attributes of links dynamically.
4. You should try to minimize redirects between domains. These will often do unintended things to query parameters and anchor text and make cross-domain tracking very difficult or impossible.

Because of all the complications involved in cross-domain tracking, you may want to consider purchasing a support plan to ensure that everything is set up correctly.

February 9, 2011 9:18 AM

Emily said:

Thanks that helps a lot. I talked to my developer about this and we're building a dynamic script to add the onClick function to the links that are moving between domains that we want to track together.
I agree that it would be best if we didn't have this highly related content on different domains and we are in the process of redesigning our overall site to include the pages that are currently on separate domains. In the mean time we really need to be able to see how users are moving through our sites.

Thank you for all your help!

February 9, 2011 10:44 AM

Eduardo Cereto said:

The argument that the leading dot can cause problems when you're changing a GA implementation is valid. But what's not clear in the post is your opinion about new implementations.

Since a new implementation doesn't have any already set cookie we should bother, than I think there's no drawback about using the leading dot.

I always use the leading dot in my new implementation, and will keep doing so.

I'm not only worried about the sub-sub-domains. But the leading dot feels more compliant with the RFC that specifies that the absence of it can cause Rejection of the cookie. I'm not sure how many browsers acctually comply to that statements, none I know of. Still I'd rather not take my chances.

http://www.ietf.org/rfc/rfc2109.txt

Quoting the RFC:
4.3.2 Rejecting Cookies
...
* The value for the Domain attribute contains no embedded dots or
does not start with a dot.

[page] 4
Domain=domain
Optional. The Domain attribute specifies the domain for which the
cookie is valid. An explicitly specified domain must always start
with a dot.

February 10, 2011 10:32 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Eduardo: I think that you can argue it either way for new Google Analytics implementations. I prefer not to use the leading period even for leading implementations (assuming of course that there aren't any sub-sub-domains). The reason is that this type of setup tends to be more forgiving when it comes to things such as rogue Google Website Optimizer tests where someone forgot to add subdomain tracking modifications.

If the RFC were an issue, then it seems like Google would have addressed this in the standard Google Analytics Tracking Code. As stands right now, if you don't do any subdomain tracking at all, then the cookies are set without the leading period. So this leads me to believe that it's a non-issue at least as far as cookie compliance is concerned.

Either way you approach this, you're going to have exceptions:

1. If you default to using the leading period, then anytime you add subdomain tracking on a site that already had Google Analytics implemented, then you'll have to consider how much of a negative impact using the leading period is going to have and possibly not use it.
2. If you default to not using the leading period, then anytime you add subdomain tracking you'll have to make sure/hope there aren't any sub-sub-domains.

For me, I find that the exceptions for #2 crop up far less frequently than for #1. Not only that, handling the exceptions for #2 is pretty cut and dry, whereas handling those for #1 involve much more of a judgment call.

Also, to be perfectly honest, I've always felt more comfortable not using the leading period. It's always felt like the right way to do it. It seems to lead to safer setups. But I can easily see how someone could have started out always using the leading period and so instead they feel more comfortable using, it feels right, it seems safer. So I'm OK with someone taking the #1 approach to it instead, but I'll probably continue taking the #2 approach.

February 10, 2011 12:49 PM

Steffen said:

Hey Jeremy, thanks for your post. Very interesting.

I'm facing the following problem: with a few days gap after deploying your recommended tracking setting, traffic from a referring subdomain drops significantly. Expected effect on _addIgnoredRef(). Meanwhile, direct traffic increases. That - in turn - is not what I expected and in my case not supposed to be. What's the benefit from tracking subdomain traffic as direct traffic? That's even more confusing than tracking as referring. I expected that traffic to become "internal" traffic. How to achieve that?
And why is that gap from ... say 10 days?

Thanks in advance.

February 24, 2011 7:56 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Steffen: I can't determine the exact cause without seeing the code or looking at the site, but if traffic from a subdomain is showing up as direct, then that indicates some type of code inconsistency between the main domain and the subdomain. Here are some things to consider:

1. Are you wanting to track the main domain and the subdomain together? Sometimes people want to track these separately, or they don't want to/can't track the subdomain for some reason and want it tracked as a referring source. This article assumes that you do want to track them together.

2. If you're tracking the main domain and the subdomain together, then the Google Analytics Tracking Code on each should be very similar, if not identical. In particular, the _setDomainName and _setAllowHash statements (or lack thereof) must be identical. You can't have a leading period on one and not on the other, use _setDomainName("none") on one and not on the other, or use _setAllowHash("false") on one and not on the other.

3. Are you running any Google Website Optimizer tests on either the main domain or the subdomain? Similar to #2, the Google Website Optimizer code must have the same set of modifications as your Google Analytics Tracking Code. This is fairly straightforward for the tracking script and conversion script, but the control script needs to be modified using equivalent urchin.js style modifications.

4. Is there any other Google Analytics Tracking Code on any of the pages? This includes legacy code, code put there by someone else for some other purpose, or even UTM code for Urchin. Any extra code like this will need to either be modified to match your Google Analytics Tracking Code or removed.

February 24, 2011 8:20 AM

Cory said:

Hi Jeremy,

This is such a great article. I recently spent a lot of time scratching my head over some self-referrals until we saw this.

I quickly implemented your code as outlined above on a simple (/path/page.aspx) www domain and a developer added matching script on a more complex transaction subdomain(pages.aspx?pid=000 etc)

Unfortunately, I'm able to see only traffic that moves from the "complex" (www) site to the "simple" (subdomain) site but not the other way around.

What do you think that means? On which CMS should I look to edit?

Thank you!

February 24, 2011 1:08 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Cory: My previous comment most likely applies here as well. In particular, you should check both sites for legacy Google Analytics Tracking Code that might have a different set of modifications than the code you just added. The legacy code will then have to either be modified or removed.

February 24, 2011 1:20 PM

Peter O'Neill said:

Hi Jeremy,

Just had a long discussion with an ex-colleague about _addignoredref and want to clarify what the impact of it is.

In point 3 of the blog, you recommend using it to avoid self-referrals when a visit session expires between pageviews. That makes sense but I can't see this causing a high percentage of self-referrals. For most sites, this should occur a minimal number of times. If a site has many visits timing out (maybe due to video), would suggest increasing length of visit.

Instead won't using this code eliminate recording of all self referrals as they will all be reported as the previous referrers or as Direct? As you say in one of the comments, this information can be useful for finding untagged pages or untagged links between subdomains.

Thanks - Peter

March 4, 2011 6:25 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Peter: Pages with a lot of content or videos can certainly exacerbate the issue, but self-referrals will often make up 1 to 2 % or more of traffic even on sites without videos or long sales letters.

I'll speculate on why and say that in general, we often don't have a captive audience on the web. Someone may be on one site, think of something and open up a tab to check something on another site, or maybe they notice they have an email, or maybe they get a phone call, etc. Depending on the type site, they may also be doing comparison shopping and have 10 different tabs open at once.

Regardless of why this is happening, _addIgnoredRef is a nice solution because it only applies to visitors that have previous referral data available. This means that a visitor won't just show up as direct instead of a self-referral, unless of course they were previously direct.

A new visitor who starts at an untagged page and moves to a tagged page will still show up a a self-referral, even if you're using _addIgnoredRef. Eventually this will happen for enough visitors that you'll see the problem in your Google Analytics reports.

This is especially true of untagged landing pages, but a page not designed to be a landing page will usually still end up as a landing page for enough people to point out the problem in Google Analytics. But if you still have the 1 to 2% of noise coming from self-referrals that could have easily been prevented by _addIgnoredRef, it makes it much harder to catch these pages.

Even if self-referrals only showed up for true problems, I'd still use _addIgnoredRef because it's more important to preserve referral information when possible than to fix a problem on a single page. If the page is important enough, then the tagging issue on that page will become obvious at some point anyway, even without a bunch of self-referrals to point it out. If it's not a very important page, then the misfortune of having that page missing from your reports is still outweighed by the benefit of having correct referral information for those visitors who spent a little too long on that page (or the previous page) for whatever reason.

March 4, 2011 7:57 AM

Peter O'Neill said:

Thanks for the detailed reply. I hadn't realised the degree to which self-referrals are driven by visitors timing out - that does change the situation.

I also agree with your logic on using _addIgnoredRef based on how you have described it as working. However that appears to be different to the Google description (which I know is wrong occasionally). They say

Excludes a source as a referring site. Use this option when you want to set certain referring links as direct traffic, rather than as referring sites. For example, your company might own another domain that you want to track as direct traffic so that it does not show up on the "Referring Sites" reports.

This suggests that all traffic from the domain specified will be reported as Direct. As opposed to what you have written which is it will pick up the previous referrer for returning visitors and have no affect on new visitors. Have you found that this is the way it works in practice and that this is another example of where Google needs to update their documentation?

March 4, 2011 12:49 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Peter: Yes, I would say that the Google documentation on _addIgnoredRef is a bit misleading. In practice, it works as I've described it.

March 4, 2011 1:07 PM

Peter O'Neill said:

Ok, that explains my confusion. Thanks for the assistance and the detailed explanations given.

March 4, 2011 1:26 PM

Rene said:

Very useful information and i did understand it until you mentioned crossdomain tracking needing a different approach with:
_gaq.push(['_setAllowHash', false]);
_gaq.push(['_setAllowLinker', true]);

What if you want to track example.com, store.example.com and example2.com together.So this would be Tracking Across Multiple Domains and one Sub-domain.

Would you use the following?

example.com
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-12345-1']);
_gaq.push(['_setDomainName', 'example.com']);
_gaq.push(['_setAllowHash', false]);
_gaq.push(['_setAllowLinker', true]);
_gaq.push(['_addIgnoredRef', 'example.com']);
_gaq.push(['_addIgnoredRef', 'example2.com']);
_gaq.push(['_trackPageview']);

store.example.com
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-12345-1']);
_gaq.push(['_setDomainName', 'example.com']);
_gaq.push(['_setAllowHash', false]);
_gaq.push(['_setAllowLinker', true]);
_gaq.push(['_addIgnoredRef', 'example.com']);
_gaq.push(['_addIgnoredRef', 'example2.com']);
_gaq.push(['_trackPageview']);

example2.com
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-12345-1']);
_gaq.push(['_setDomainName', 'example.com']);
_gaq.push(['_setAllowHash', false]);
_gaq.push(['_setAllowLinker', true]);
_gaq.push(['_addIgnoredRef', 'example.com']);
_gaq.push(['_addIgnoredRef', 'example2.com']);
_gaq.push(['_trackPageview']);

March 15, 2011 5:31 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Rene: The code for example2.com should be a little different:

var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-12345-1']);
_gaq.push(['_setDomainName', 'example2.com']);
_gaq.push(['_setAllowHash', false]);
_gaq.push(['_setAllowLinker', true]);
_gaq.push(['_addIgnoredRef', 'example.com']);
_gaq.push(['_addIgnoredRef', 'example2.com']);
_gaq.push(['_trackPageview']);

It'd important that the _setDomainName call match the root level domain of the site the code is on. If it doesn't match, then no cookies will be set and you won't get any Google Analytics data for those pages.

March 15, 2011 7:51 AM

Jeff said:

What if I want to track all of my subdomains independently? How do I set that up?
Each of my clients will have a branded website for themselves that I am hosting as a subdomain. I need to be able to generate a report showing Client A his traffic without any other clients info in there.
Currently we only have about 8-10 of these clients but the number is growing and could reach into the hundreds.
Any suggestions for this GA challenged guy?
Thanks in advance!
Jeff

March 28, 2011 4:19 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Jeff: See the comment at the end of the this post.

March 28, 2011 5:03 PM

Jeff said:

Thank you! I didn't realize there was a different post and kept looking at this one for a reply.
Thank you again!

March 30, 2011 12:59 AM

anobre said:

Hi there!
I've implemented this tracking code style and it seems to be working great with a catch. Now when i go , for instance, to top content report and click 'visit link' i'am always sent to the top domain when in most cases i should be redirected to a subdomain.

Cheers,

April 14, 2011 3:11 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@anobre: You'll need to add two steps to this:

1. Add a filter to add the hostname to the beginning of the request uri. Usually I use something like this:

Filter type: Custom Filter (Advanced)
Field A: Hostname
Extract A: (.*)
Field B: Request URI
Extract B: (.*)
Output to: Request URI
Constructor: $A1$B1
Field A Required: Yes
Field B Required: Yes
Override Output Field: Yes

2. Edit the Main Website Profile Information and change the Website URL to:

http://

This won't fix the existing data in your profile, but going forward, clicking on a link will go to the correct subdomain. This works for sites with multiple domains as well.

April 14, 2011 3:44 PM

Ryan said:

Hi Jeremy - great post. I was trying to follow along your comment discussion with Rene about cross-domain with sub-domain tracking but believe I missed something.

If I am tracking from www.mainstore.com (or mainstore.com) to 3rd party checkout which is a sub subdomain: checkout.sub.main.net - is what I have correct:


Site (mainstore.com):
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-XXXXX']);
_gaq.push(['_setDomainName', '.mainstore.com']);
_gaq.push(['_setAllowHash', false]);
_gaq.push(['_setAllowLinker', true]);
_gaq.push(['_setAllowAnchor', true]);
_gaq.push(['_addIgnoredRef', 'mainstore.com']);
_gaq.push(['_trackPageview']);


3rd Party (checkout.sub.main.net):

var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-XXXXX']);
_gaq.push(['_setDomainName', '.main.net']);
_gaq.push(['_setAllowHash', false]);
_gaq.push(['_setAllowLinker', true]);
_gaq.push(['_setAllowAnchor', true]);
_gaq.push(['_addIgnoredRef', 'mainstore.com']);
_gaq.push(['_addIgnoredRef', 'main.net']);
_gaq.push(['_trackPageview']);


Does that look correct (assuming the linker tags are in place)?

April 14, 2011 4:30 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Ryan: That code looks fine. The one thing I would add is that the _setDomainName call is optional for the third party domain unless you're tracking across subdomains on the third party domain. That is, if a visitor goes from your site to checkout.sub.main.net and doesn't see any other subdomains on main.net, then there's no need to do subdomain tracking for the third party domain.

Also, if you have two sites, one with sub subdomains and the other without sub subdomains, technically you only have to use the leading period on the site with sub sub domains. So even if a visitor could go from checkout.sub.main.next to somewhere else on main.net, that doesn't mean you need a leading period for mainstore.com as well.

As discussed in the article, you can certainly still include the leading period if you feel strongly about it, but there are benefits to not using the leading period which you might be able to take advantage of. It might also be difficult to remember which sites you have to use it for and which you don't, in which case always using the leading period may make more sense.

April 14, 2011 4:52 PM

Ryan said:

Great, I will try taking out the leading periods. Thank you Jeremy

April 14, 2011 4:55 PM

Brian Moore ? said:

Some thing tells me I ruined/fubar'd my analytics.

ok I have a ecommerce site using a 3rd party shopping cart.

my analytics code is this:
mysite.com

var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-*********-1']);
_gaq.push(['_setDomainName', 'none']);
_gaq.push(['_setAllowLinker', true]);
_gaq.push(['_setAllowHash', false]);

3rd party cart
cart.com

var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-********-1']);
_gaq.push(['_setDomainName', 'none']);
_gaq.push(['_setAllowLinker', true]);
_gaq.push(['_trackPageview', 'insert_page_name']);


ever since i implemented this code change so my boss could get the google adwords conversion tracking working the main site shows up as a referrer and now the ecommerce conversion rate in google analytics has droped to zero.

help please.

April 19, 2011 1:35 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Brian: I don't see a _trackPageview call for the mysite.com analytics call, but you may have just left that off. It's also not necessary to have both _gaq.push(['_setDomainName', 'none']); and _gaq.push(['_setAllowHash', false]); on the mysite.com code. You should probably drop the _setDomainName call.

My best guess is that you probably had some sort of linking in place that is now broken as a result of updating your code to the async version. Without knowing anything else, the easiest way you can probably fix that is to add the following after your Google Analytics Tracking Code:

_gaq.push(function() {
window.pageTracker = _gat._getTrackerByName();
});

You can add this after both your mysite.com code and your 3rd party code, assuming that the 3rd party domain links back to your main domain correctly.

April 19, 2011 2:45 PM

Ryan said:

Hi Jeremy,

Unfortunately I am still getting mostly (direct) transactions in my reporting. About 1/3 do contain the referring keyword so I believe I must be on the right track but am perhaps missing something.

This is with a Yahoo! store and I believe I have to the two links tagged correctly that point to the cross-domain from sunshineyoga.com to checkout:(yahoo.net).

Can I pay you to review at my implementation (via view source) to make sure I have the cross links tagged?

When I run through in WASP it looks like the cookie retains all the data so I'm not quite sure what the issue is.

Thank you!

April 20, 2011 11:01 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Ryan: We no longer offer stand-alone Google Analytics support plans. You should look into using Monitus in order to track Yahoo Store. That is what we always recommend for tracking Yahoo Store.

April 20, 2011 12:20 PM

Ryan said:

Do you have anyone you can refer me to?

Not really interested in having to pay monthly for GA data.

Thanks!

April 20, 2011 2:37 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Ryan: Monitus is the only viable solution for tracking Yahoo Stores. So if you don't want to pay monthly, you'll probably want to look into using something besides the Yahoo Store.

April 20, 2011 3:01 PM

Dan said:

If my sub domains have no reference or relationship to the TLD, would I not get valid results if I treated the sub domain the same as a TLD?
I setup a site in a WP multi site environment so wouldn't I just treat the sub domain the same as a TLD, generate and implement analytics the same way I would for a TLD?
Dan

May 2, 2011 10:34 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Dan: If the subdomain does not refer to the main domain and vice versa, then you do not need to implement subdomain tracking. The standard Google Analytics Tracking Code will work fine for both sites. You can either use separate account numbers (within the same Google Analytics account) to track each domain separately, or use the same one if you want roll-up reporting.

The same goes for multiple domains as well. If you have multiple domains and no domain links to any of the other domains, then there's no need to implement cross-domain tracking. The standard Google Analytics Tracking Code will work fine for all sites. And again, you can track the sites separately or in a roll-up profile (or both).

May 4, 2011 8:03 AM

Eric W said:

Hi Jeremy - great article. I recently added similar code in an attempt to fix self-referrals for our websites. The result was partially successful, they dropped dramatically for April (implemented 3/31).

However, we also experienced a massive unexplained drop in Visits and UV's, while our PV and every other performance metric increased.

Is there any reason that getting rid of self-referrals would lower UV's (or, to phrase properly, improperly having self referrals would have been inflating UV counts?)

Thanks,
Eric

May 9, 2011 9:20 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Eric: Self referrals will usually result in inflated visit counts. Inflated UV counts are less common, but this is also possible depending on what your code looked like before. Unique visitor counts are largely based on the __utma cookie remaining intact. So if your Google Analytics Tracking Code setup results in this cookie being recreated, then you will get an artificial spike in UVs.

May 10, 2011 7:59 AM

Eric W said:

Thank you very much! I was able remove my fix and test it and actually see the Unique Visitor ID change, creating extra UV's. Appreciate your feedback!

May 10, 2011 11:06 AM

Eric said:

Another question for you Jeremy.

Our sites have 1 main domain and 1 main subdomain. We get a ton of self referrals and corrected some of them by adding 1 missing line of code to our main domain pages.

However, we are still getting quite a few.

Here is the code we are using. Is this correct?


var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA of Main Page']);
_gaq.push(['_setDomainName', '.ericsite.com']); (this line was missing and was added 5 weeks ago, fixing about 60% of our self referrals)
_gaq.push(['_trackPageview']);

_gaq.push(['_setAccount', 'UA of rollup account']);
_gaq.push(['_setDomainName', '.ericsite.com']);
_gaq.push(['_trackPageview']);
_gaq.push(['_setAccount', 'UA of another rollup account']);
_gaq.push(['_setDomainName', '.ericsite.com']);
_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);
})();

May 12, 2011 4:30 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Eric: As mentioned in the post you should also add the following line for each account:

_gaq.push(['_addIgnoredRef', 'ericsite.com']);

This line can go right after the _setDomainName line for each account. Also note that I intentionally left out the period in front of ericsite.com. This is correct regardless of whether you use a leading period with _setDomainName or not.

May 12, 2011 4:45 PM

Eric said:

Thanks again, will report back results!

May 12, 2011 9:14 PM

Eric said:

Greetings again -

The addition of that code has had no impact. If we had our sites live for a solid 6 months with a subdomain issue, is it possible/likely that the remaining self-referrals we still see after fixing things are simply "baked" in to cookies and not fixable until the cookie expires?

Very much at a loss now.

Thanks again!
Eric

May 23, 2011 7:46 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Eric: Yes, it may take some time to work itself out. Not only do you have return visitors who already have cookies for self-referrals, but you also potentially have return visitors who are viewing cached pages with the old code that may still have their referral information overwritten with a self-referral.

Also note that this code change doesn't address other fixable sources of self-referral traffic. For example, if you have a landing page that's missing the tracking code altogether, the code change won't fix those self-referrals, but you can still fix the issue by adding the tracking code to that landing page.

May 24, 2011 7:13 AM

Eric said:

Couple more things.

#1 - I've had one site that has been fixed for 3 months now (2/22 fix date). That being the case, I'd expect their remaining self-referrals to be slowly dropping off over time. However, they are staying pretty flat since the initial drop from my 2/22 fix. That concerns me.

#2 - I added the hash setting to the site I tried your suggestion on last week. It now looks like this :
var _gaq = _gaq || [];
_gaq.push(['_setAccount', '']);
_gaq.push(['_setDomainName', '.ericsite.com']);
_gaq.push(['_addIgnoredRef', 'ericsite.com']);
_gaq.push(['_setAllowHash', false]);
_gaq.push(['_trackPageview']);


While the addition of addIgnoredRef last week had no impact on the self-referral count, the addition of setAllowHash false seems to have had a definite impact in lessening the self-referrals.

Does that make any sense to you?

Are there any drawbacks to turning off the hash like that?

Thanks again!
Eric

May 25, 2011 2:02 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Eric: Turning the hash off would cause a cookie reset for all your return visitors. So while this does remove all of the lingering self-referrals, it also removes all of the referral attribution for all of your return visitors. Most likely you're now seeing a jump in direct traffic.

May 26, 2011 7:37 AM

Eric said:

Yep - that's exactly what happening. Direct jumped from 32% to 49%.

Is the cookie reset from turning off hash a 1 time thing?

In other words, if I leave it as is, are the cookies being constantly reset for the same user over and over?

Thank you sooo much for the assistance. Invaluable.

May 26, 2011 1:48 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Eric: The cookies will only be reset a maximum of once per user, and only for users visited the site prior to the code change. For new visitors, the cookies will be set correctly for the first visit and will not be reset for subsequent visits (though of course standard attribution rules apply).

May 26, 2011 3:16 PM

Jonathan said:

Hi Jeremy - fantastic post, I've been looking for a way to fix our self-referral issue for a very long time.

Before I implement the changes you suggest (i.e. add addIgnoredRef) , a quick question about leading periods:

We've been using Google Analytics across multiple subdomains (but no lower level domains) for over a year, and have always used setDomainName with a leading period. I know you generally recommend not to use the leading period when making the "switch" to subdomain tracking, but what would you do in our situation, given that we've already used the leading period in setDomainName for such a long time?

Thanks for your help!
Jonathan

June 1, 2011 12:58 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Jonathan: If you've been using the leading period the whole time, then you're probably better off sticking with it. The main exception would if you've often had cookie corruption due to things like poor Google Website Optimizer implementations. In that case, moving to not using the leading period would still cause an initial cookie reset, but might prevent additional cookie resets down the road.

June 1, 2011 5:31 PM

Doug Gebhardt said:

What an amazing post. Thanks so much Jeremy. Looks like it has kept you hopping! I'm wondering about what happens when www2 is showing up in my referral traffic as the number 1 referrer. Would this help to eliminate this sort of self referral? Here is what we have right now.
var pageTracker = _gat._getTracker("UA-1234567-1");
pageTracker._setDomainName(".sample.ca");
pageTracker._setAllowLinker(true);
pageTracker._setAllowHash(false);
pageTracker._trackPageview();
Based on your other answers here, the leading period should be removed in the setDomainName as well to prevent the subdomains as showing up as referrers.
Cheers!

June 5, 2011 9:44 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Doug: The main reason for leaving off the leading period is that it creates cookies that are compatible with the standard, unmodified Google Analytics Tracking Code on your main domain. If you're using the leading period and already have for a while, then switching will cause a cookie reset. Also, whether or not you use the leading period does not affect whether or not you have self-referrals.

Adding the following line should help with some of the self-referrals:

pageTracker._addIgnoredRef("sample.ca");

As mentioned in the post, the leading period should not be used for this method, regardless of whether or not you use it in your _setDomainName call. This call can go right after _setDomainName call.

It's always possible that there may be some other reason why you're getting self-referrals, but this addresses one source of self-referrals caused by subdomain tracking in general.

June 6, 2011 7:26 AM

Devendra Singh said:

Quite informative post, especially because it even tries to correct some documentation mistakes of GA.

A small query please:
We have couple of websites on subdomains. Each one does its own SEO to attract Search Engine Traffic. The Visitors may land to any of the subdomain websites from Search Engine Referral. Later if the Visitor clicks a link to move to the sister subdomain, we still see the original source as the Referral Site. That's okay. But, is there a way to track that how many referrals were transferred to each other (without event tracking)?

Thanks,

DS

July 3, 2011 12:19 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Devendra: You could probably do this to some extent with custom variables or internal site search tracking. Another option would be to use a second tracking object. This would look something like this:

_gaq.push(['_setAccount', 'UA-XXXXXXX-1']);
_gaq.push(['_setDomainName', 'mydomain.com']);
_gaq.push(['_trackPageview']);

_gaq.push(['t2._setAccount', 'UA-XXXXXXX-2']);
_gaq.push(['t2._setDomainName', document.domain]);
_gaq.push(['t2._trackPageview']);

The idea here is that the first tracking object will have its cookies set to the root level domain, while the second tracking object will have its cookies set to the entire domain, including the subdomain. Some key things to notice:

1. Two separate accounts are used (UA-XXXXXXX-1 and UA-XXXXXXX-2).
2. 'mydomain.com' is a string while document.domain is not
3. This will only work reliably well in single domain with subdomain situations.
4. For the same reason as #3, do not use _gaq.push(['_setAllowHash', false]); even if you see documentation that says that you need to for subdomains.

July 5, 2011 7:45 AM

Ruby said:

Hi Jeremy, thanks for writing the article. It is very useful. I am new to GA. I have few questions about subdomain tracking.

I have a website site with sub.example.com and subsub.sub.example.com. The subsub.sub.example.com is not a brand new site so I should use

_gaq.push(['_setDomainName', '.example.com']);

to allow leading time for the site. With the dot in front of the domain name. Is it correct?

The code below should be in both sub.example.com and subsub.sub.example.com sites:

var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-12345-1']);
_gaq.push(['_setDomainName', '.example.com']);
_gaq.push(['_addIgnoredRef', 'example.com']);
_gaq.push(['_trackPageview']);

Also there is another subdomains under the same domain name, for example abc.example.com and efg.example .com. Will the code above track traffic from the other sub domains as well?

Many thanks

July 13, 2011 9:40 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Ruby: Your code looks correct. Because you have multiple levels of subdomains (e.g. subsub.sub.example.com), the leading period is strictly necessary. The same code works for just one level of subdomains (e.g. abc.example.com). The addIgnoredRef call is also correct; no leading period gives you the best coverage since this is simply a substring match using indexOf.

July 14, 2011 10:52 AM

webzdev said:

Hello Jeremy thnak you very much for your post. It was like hell for me to clarify to myself what is right and what is wrong.

I have following situation:
A year ago I did set up GA on a domain example.com BUT code looks like this:
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-xxxxxx-y']);
_gaq.push(['_setDomainName', '.example.com']);
_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);
})();

now I created a subdomain sub.example.com created a separate Profile in GA dashboard. Now I have 2 profiles for site url example.com. I copied GA code suggested by google, pasted it on sub.** but code looks like tihs:
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-xxxxxx-y']);
_gaq.push(['_setDomainName', '.example.com']);
_gaq.push(['_trackPageview']);
(it is the same as this on my main domain) I notice in dashboard there are different profile IDs but they are not addressed in the GA code.

I am confused what exactly should I do to track my subdomain AS A FULLY INDEPENDENT site.
Should I add sub.example.com as new site so I receive a different code or should I retain the second profile with some adjustments??

July 24, 2011 12:25 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

When you add a new profile, you should select the option to add the profile for a new domain rather than an existing domain. This will give you an account number that's separate from your existing profile. Note, however, that the only difference between the two account numbers will be the "-y" at the very end of the number. This is sufficient to track the sites separately.

Also, since you're tracking this subdomain separately, you may want to consider removing the _setDomainName line, to avoid sharing cookies between this subdomain and your existing site.

July 25, 2011 9:16 AM

Vikas Sahdev ? said:

Hi Jeremy,
You are the recognized GA expert here, so I would ask your advice. In between reading multiple threads, I am sort of confused and want to clarify whether what I am doing is correct.

I have two sites: www.example.com and a subdomain www.blog.example.com

What I want is:

1. Sub domain tracking

2. One GA Profile which tracks both the main domain and sub domain.

3. Conversion funnel from all pages on the www.blog.example.com to www.example.com

This is what I have done so far:


1.
I added the below code to www.example.com and www.blog.example.com:

var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-XXXXXX-1']);
_gaq.push(['_setDomainName', 'example.com']);
_gaq.push(['_addIgnoredRef', 'example.com']);
_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);
})();

2.

Created one Master Profile in GA( for www.example.com) without any filters


3.

Created a duplicate of the Master Profile in GA( for www.example.com) with the subdomain filter described earlier in the thread.


Below are the Questions I have:

1. Does the above set up look correct considering what I want to achieve?
2. It has been a day since I set up the second profile but still don't see any visits. Any ideas if something is wrong?
3. I want to implement a funnel whereby i want to track how many visitors from anywhere on www.blog.example.com came to www.example.com. Both the sites don't have default pages in the url( i.e no www.blog.example.com/default.aspx e.g). So in the funnel, how do i define step1 and step 2 urls since both sites have "/" as their default page?

4. Since both the profiles I have contain data from both sites, how do I "filter" reports for one site vs the other? For e.g I woudl like to know the unique visitors to only the blog site and not the main domain site. Is that possible?


Thanks a ton for your help looking into this.


July 29, 2011 5:32 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

Your best bet is to probably use an advanced filter for visits that include both hostnames. You could set this up as a goal, but it would only be useful if you checked the required step box, and even then only within the Funnel Visualization report. When you have a filter that modifies the request uri, the Goal URL and Funnel Steps should match the modified request uri instead, which means that you can do a head match on blog.example.com and www.example.com. The main thing to check if there's still no data is that the other profile is a duplicate of the other one, that is, the web properties should be the same. It's easy to create another profile that uses a -2 instead of a -1 in its Google Analytics Tracking Code.

August 1, 2011 5:29 PM

Vikas Sahdev ? said:

Thanks Jeremy. I have two more questions from your original article:

1. _gaq.push(['_addIgnoredRef', 'example.com']);

If I put the above line in the GA code, both for root domain and subdomain, would I still see the traffic coming from www.blog.example.com to www.example.com. Since I would like to track conversion from the blog site(sub domain) to main site( root domain), I don't want to loose the referrals from blog site to main site.

What reports exactly get impacted by using the code line above? Is it only the Reffering sites report?


2. _gaq.push(['_setDomainName', 'example.com']);

We had a separate GA ID for the subdomain and root domain and thus separate profiles in GA for each of those and we were using leading period in the setDomainName. This was happening for over a year.

Recently we started using the same GA ID for the subdomain and root domain and one profile for both sites with the cross domain filter applied.

In this situation, do you recommend that we keep the leading period or remove it in the above line of code ?

I am also confused by your original comment in the article which says "What this means is that if you weren't doing subdomain tracking previously".

I am not sure what exactly constitutes "doing subdomain tracking" to be able to say whether that condition applies to us. What I am doing is summarized in the previous post. Does that constitute what you meant by "doing subdomain tracking"?


Thanks again!!

August 9, 2011 7:01 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Vikas: _addIgnoredRef is a soft ignore, that is, it only ignores the referrer if there is pre-existing referral information. For example, if your tracking code is set up so that someone starting on the blog and moving to the main domain is counted as a blog referral, then adding _addIgnoredRef won't change that. If instead someone starts on the main site, moves to the blog, then moves back to the main site, then they will not count as a blog referral, even if they spent more than 30 minutes on the blog, because there were already cookies on the main site.

If you were previously using the leading period with _setDomainName, it's probably best to continue using the leading period unless you've been having problems. For example, if someone keeps setting up GWO tests and they can't remember to add proper subdomain tracking modifications, dropping the leading period might help alleviate some of those issues.

"Doing subdomain tracking" refers to using _setDomainName to share cookies across subdomains, regardless of whether you used the leading period. If you have subdomains, but you're not using _setDomainName, then you're not doing subdomain tracking because each subdomain is more or less being treated as a separate site.

In your scenario, it sounds like you want to be able to see traffic that's referred from the blog. In that case, using any form of _setDomainName doesn't make sense because you don't want the cookies to be shared between the two subdomains. _addIgnoredRef probably isn't a bad idea though since it will only give the blog credit when they came to the blog first. You won't easily be able to tell which keywords that sent visitors to the blog resulted in conversions on the main site, however, since those conversions will be credited to the blog instead of the keyword.

August 10, 2011 7:34 AM

Darius said:

Hi,

I tried this but it doesn't work. It still double counts visits over sub-domains, but now it just comes through as all direct. (I implemented it on a website which gets no traffic - so it was a controlled test).

The implementation suggested on the GA website also doesn't work. It ends up with loads of self-referrals.

August 11, 2011 5:47 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Darius: It's hard to know what the issue is without seeing the site. Normally with something like this I would use a cookie viewer like firebug with firecookie and a headers viewer like httpfox so I can see exactly when the issue occurs. Usually you can just use some fake tags like http://www.example.com/?utm_source=test&utm_medium=test&utm_campaign=test and then see when the cookies change to direct.

It may be that there's some rogue code on the page that doesn't have proper subdomain modifications that's causing the issue. This code could be legacy code that's still on the page, Google Website Optimizer code, or possible urchin Urchin UTM code.

August 11, 2011 7:53 AM

Tauseef said:

Hi Jeremy,

Thanks for the information. I update the code to track sub domain and domain traffic. I have two top level domain mobile.customizedstickers.com
blog.customizedstickers.com

The one I am more want to see not as a referral traffic is mobile cause I get conversion from that (Paid and Organic). After changing the code Now getting traffic as a direct.

Any idea why it's doing it or just a old cookies kicking in.

Any help will be highly appreciable.

Thanks in advance.

Tauseef

August 11, 2011 5:16 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Tauseef: Most likely the direct traffic is return traffic to the site. Because both of your domains are subdomains, the cookies by default would have been at the subdomain level. Now that you've implemented subdomain tracking, cookies will be read and created at the root level domain. This means that you may lose information for returning visitors. Over time, this number should decrease and the percentage of direct traffic should go down.

August 12, 2011 9:43 AM

Owen Smith said:

Hi Jeremy,

Perhaps you can help me out with an issue I'm having.

I have a website like so: mysubdomain.x.x.ca

I store static content (css, js, etc) at: static.mysubdomain.x.x.ca

Now, I don't want cookies to get set on the static subdomain for caching purposes.

On my pages, my tracker looks like :
var _gaq=[
['_setAccount',''],
['_setDomainName', 'mysubdomain.x.x.ca'],
['_trackPageview']
];

However the cookies are still set as ".mysubdomain.x.x.ca"

Can you provide any insight on not including lower-level subdomains?

August 14, 2011 2:54 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Owen: If you explicitly need cookies to not be available for any other domains, then you'll need to use something like this:

_gaq=[
['_setAccount',''],
['_setDomainName', 'none'],
['_trackPageview']
];

Then the cookies will only be available to the domain they were set on. Note that this will also affect the hash, so you need to be careful to check that this works as you expect it to. Also, it might be best not to explicitly set _gaq to an array. _gaq is only temporarily an array; it's later rewritten as an object. So it might not always work as expected.

August 15, 2011 8:05 AM

Ken Holden said:

Would this work for issues regarding a secure subdomain? The site is www.planetdj.com. The user is sent to secure.planetdj.com upon beginning check out. (Feel free to see for yourself).
This is the current code we have implemented.


var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-605157-1']);
_gaq.push(['_setDomainName', 'none']);
_gaq.push(['_setAllowLinker', true]);
_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);
})();

All of our conversions are listed as (direct) / (none).

It's not a referral issue, which is why I ask.

Your help would be awesome. Thanks! Great article!!

August 24, 2011 5:02 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Ken: I would recommend something along these lines:

var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-605157-1']);
_gaq.push(['_setDomainName', 'planetdj.com']);
_gaq.push(['_addIgnoredRef', 'planetdj.com']);
_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);
})();

These modifications will track visitors as they move across subdomains of planetdj.com. As long as everything is on planetdj.com, there's no reason to implement cross domain tracking modifications (_setDomainName('none') or _setAllowHash(false), _setAllowLinker(true), etc.).

August 25, 2011 7:28 AM

Ken Holden said:

Yeah that still didn't work. Would there be interference with the cookies? All our conversion traffic is still labeled as (Direct)/(none).

Care to take a peek? Feel free to start the checkout process, as I feel that's where the issue starts.

August 25, 2011 5:28 PM

HopeThisHelps said:

Note that _setAllowHash() has now been deprecated:

http://code.google.com/apis/analytics/docs/gaJS/gaJSApiDomainDirectory.html#_gat.GA_Tracker_._setAllowHash

and the recommendations on the Google site are now a lot closer to the above. I think they are listening ;-)

September 9, 2011 4:14 AM

David said:

Here is the situation our websites share a main navigation / design thus you can easily navigate between 'www.a.com', 'www.b.com' and 'www.c.com' we also have two subdomains of 'www.a.com' that each website uses for quotes & sales those subdomains are: 'secure.a.com' and 'sale.a.com'.

So if you are on 'www.a.com' and click a main navigation item you could go to 'www.b.com' once there say you add an item to your shopping cart you are take to 'secure.a.com'

Here is the solution we have implemented:

On each domain / subdomain we have placed this code:

_setDomainName is the only thing that changes and reflects the domain or subdomain you are on i.e. in this case ".a.com" on the other domains / subdomains it reads ".b.com", ".c.com", ".secure.a.com" and ".sale.a.com".

var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-XXXXX-1']);
_gaq.push(['_setDomainName', '.a.com']);
_gaq.push(['_setAllowLinker',true]);
_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);
})();

$('a').click(function() {
var url = $(this).attr("href");
if (url)
{
if (url.substring(0, 4) == 'http' && url != '' && url != '#' && url.toLowerCase().indexOf('youtube') {
if (url.substring(0, 4) == 'http')
{
_gaq.push(['_link',url]);
location.href = url;
}
return false;
}
}
});

Here are the questions:

We have noticed a large bump in average time on site, why, and how do we correct this?
Have we setup the code properly for multiple domain tracking & subdomain tracking?

September 16, 2011 10:49 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@David: The code looks reasonable. The _setAllowHash method has been deprecated; it's no longer necessary for cross-domain tracking, but it doesn't hurt much to leave it in. It also looks like you'll potentially be tagging all outbound links, not just the ones to your other domain, but it is easier to implement this way than to check each link against the list of your domains before tagging.

The bump in average time on site makes sense because you're maintaining the session across domains whereas before the session would break as you moved from domain to domain. For example, if you spent 3 minutes on a.com, 3 minutes on b.com, and 3 minutes on c.com, your average time on site in the old model would be 3 minutes, but in the new model it would be 9 minutes.

September 16, 2011 11:27 AM

Nick Budden said:

Hi Jeremy,

Thank you for the great post, I've been search for something like this for quite some time. I'm running a Wordpress network using subdomain installs, and currently all of my sites are being tracked using a single profile. What I hope to accomplish is to have one profile that tracks my primary domain AND my subdomains, and also to have an individual profile associated with each of my individual subdomains. I have a relatively small number of subdomains, and can customize my code for each if needed (i.e. my wordpress users cannot create their own subdomains...the solution does not need to be very dynamic). What would you suggest as the best solution for this?

Again thank you for the article!

October 5, 2011 3:50 PM

Kamran Jamshidi said:

This has been bookmarked, informative and well explained.

Using: _gaq.push(['_addIgnoredRef', 'example-petstore.com']); to filter own things away is useful.

Same goes with search engine reports etc from analytics, you get more clean data using features like:
_gaq.push(['_addIgnoredOrganic', 'www.mydomainname.com']);

October 10, 2011 6:02 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

While it's possible to track everything with a single account number and create the profiles for individual subdomains using filters, it probably makes the most sense to set up a second tracker for each subdomain with a separate account number. The reason is that there are types of hits that cannot be easily excluded using filters, which would show up in all of your profiles unless you took additional measures. This behavior is not well-defined, so you are best off using separate accounts.

Note, however, that these can simply be sub accounts within your main GA account. The profile for your main site might use UA-12345678-1, while the profiles for your subdomains might use UA-12345678-2, UA-12345678-3, etc. Also, the code for each subdomain should probably have the same subdomain modifications as your global tracking code unless you have specific reasons for not doing so. This can help to avoid subtle issues like having global tracking code that includes a leading period on your main site along with tracking code just for the main site that has no subdomain modifications, but in fact includes subdomain tracking that does not use the leading period by default, resulting in a hash conflict.

October 11, 2011 8:04 AM

justin brock said:

Great article, Jeremy.

Google recently updated the subdomain tracking video on Conversion University. In it they advise the leading period. http://services.google.com/analytics/breeze/en/domains_subdomains/index.html

Is your advice still not to use the leading period for those of us who only have subdomains, as opposed to lower-level subdomains?

October 13, 2011 12:20 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Justin: Yes, I still prefer to not use the leading period in situations where there are no lower-level subdomains. Lower-level subdomains are the only situation where a leading period is required. Not including the leading period tends to result in more forgiving tracking code. If someone manages to put up a page without code or the incorrect code, if they launch a website optimizer test, or if they were previously not previously doing subdomain tracking and update their code to include subdomain tracking modifications--all of these situations are handled much better without the leading period.

October 13, 2011 1:35 PM

Dan Lyons said:

Hi Jeremy,

Here's the issue I'm trying to solve:

I have multiple sites with different product catalogues.

SiteA.com - primary site. All shopping cart conversions happen through here. It has multiple subdomains.

SiteB.com - separate domain with no subdomains, has online store. But when an item is "added to cart" on this site, it sends the visitor to SiteA.com to complete the purchase. There is a unique "added to cart" page on SiteA.com that a visitor only sees if they came from SiteB.com - think of it as SiteA.com/cart/SiteBcart-addedtocart. This means anytime we see a pageview of SiteA.com/cart/SiteBcart-addedtocart in the GA reports, it means they were on SiteB and added something into their cart.

We're collecting all data into one profile - this includes SiteA.com and its subdomains and SiteB.com. Code we're using on SiteA.com and its subdomains is as follows:

var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-123456-1']);
_gaq.push(['_setDomainName', 'sitea.com']);
_gaq.push(['_setAllowHash', false]);
_gaq.push(['_setAllowLinker', true]);
_gaq.push(['_trackPageview']);
_gaq.push(['_trackPageLoadTime']);

SiteB.com code:
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-123456-1']);
_gaq.push(['_setDomainName', 'siteb.com']);
_gaq.push(['_setAllowHash', false]);
_gaq.push(['_setAllowLinker', true]);
_gaq.push(['_trackPageview']);
_gaq.push(['_trackPageLoadTime']);

We've tagged all links sending someone from siteb.com to sitea.com with linkbypost.

The issue: while we're tracking visitors successfully on both domains and subdomains, it seems the cookie is getting dropped when an item is placed in the cart on SiteB.com. When I look in the content report and segment down everyone who saw SiteA.com/cart/SiteBcart-addedtocart (visitors I know could only have come from siteb.com to sitea.com after placing an item in their cart) and then use a secondary dimension to identify their source, I'm seeing them as referrals from SiteB.com. I would also expect their landing page to be somewhere on SiteB.com, but landing page is showing up as SiteA.com/cart/SiteBcart-addedtocart.

Would appreciate your thoughts on why the cookie might be getting dropped in this instance.

Thanks!

October 15, 2011 10:42 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Dan: When you tag the links from one domain to the other, the cookie information from the first domain is passed to the second domain through the query string. Oftentimes with carts, these query parameters can become corrupted or may be stripped from the final URL altogether. You would need to confirm that this isn't happening. If it is, then there may be a way to work around it, but it will likely be rather complicated.

October 17, 2011 8:47 AM

ryan said:

Great article. Now for the code you recommend.... Does that go on both the main url and the subdomain? Thanks. Ryan

November 2, 2011 2:10 PM

Kim K said:

If the link to open the subdomain opens in a new window, will that cause a new session to be started? I have the correct codes on the domain and subdomain, but I see that a cookie is being writtem for the subdomain and it doesn't contain the original referrer data. Want to tell my client that they should open the links to the subdomain in the same window. I have never run across this particular "flavor" of setup, although I have coded up dozens and dozens of cross domain tracking setups.

November 23, 2011 2:47 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Kim: Opening the subdomain in a new window should not affect cookies. If cookies are being written improperly, then that means there is some issue with the Google Analytics Tracking Code on the subdomain. Even if the code on the subdomain is correct, it's possible that Google Website Optimizer code, Google Analytics Tracking Code from another vendor, or 3rd party code with built-in Google Analytics Integration might create a second second set of cookies for the subdomain.

November 28, 2011 9:08 AM

Nate said:

Great Post. Quick question. We are tracking multiple subdomains and top level domains on one tag. I noticed a lot of self referrals and came across this post. But have discovered something else. My issue is with the subdomains. One subdomain did not get updated with the GA tag. It had no tag at all. This subdomain is commonly hit when passing between two other subdomains. With this tag being absent, how bad did we mess up our data over that time? So if the users path was as follows (and it always will be):

subdomainA.domain.com > subdomainB.domain.com > subdomainC.domain.com - what did this do to our data?

Obviously we got a referral from subdomainB when, and lost our correct referral information I assume, and did not get page views on subdomainB, but did we also inflate visit count? Did we get a visit when they landed on A and exit when they landed on B and then a new visit when they landed on C?

I know that's a little off topic of this post, but if you have some insight that would be great.

December 15, 2011 2:45 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Nate: In Google Analytics, a session ends when there has been more than 30 minutes between pageviews. When the session ends, this means that the next pageview will result in a new visit and that the referral information of the visitor is subject to being updated. If it's been less than 30 minutes, however, then the referral information will not update unless it's something other than a site referral (i.e. tagged or organic).

This means that you will only get self-referrals when the visitor has spend more than 30 minutes on subdomainB. This also means that whenever the source changes from something else to a self-referral, a new visit has resulted with a new landing page and the visit count has been inflated.

December 15, 2011 3:38 PM

Saul said:

Hi! Thanks for this useful article. I have a one domain and 2 subdomains with your code implementation. But I don't know how track visitors from one subdomain to another..I mean how many new visitors has come to a subdomain and then went to another subdomain for example.

Sorry for my english.

December 23, 2011 6:15 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Saul: This code is for tracking a domain and its subdomains as a single site. When this is implemented, traffic moving from one subdomain to another is not as visible as it would be with the default code. If it's more important for you to see the subdomains as separate sites, then it may be better to just stick with the default code. There are ways to set up two accounts in Google Analytics and track subdomains both ways, as separate sites and as a single site, but this can be tricky to get right. The main concern is that cookies will likely be shared on the main domain unless you make sure to always resolve to www and the account that tracks subdomains individually explicitly sets the domain name to the FQDN (e.g. _gaq.push(['t2._setDomainName', 'www.domain.com']); or _gaq.push(['t2._setDomainName', document.domain]);).

December 27, 2011 10:14 AM

Blanka said:

Hi Jeremy,

the article is great, although I still have troubles with setting the subdomains tracking. We have a big media site with multiple subdomains, but just one parent domain. After customizing the tracking code we got rid of self referrals, but we noticed a huge drop in pageviews, which just doesnt make sense to me. Is there any explanation of why that happens? The code was the following:

_gaq.push(['_setAccount', 'UA-XXXXXXX-1']);
_gaq.push(['_setDomainName', 'mydomain.com']);
_gaq.push(['_trackPageview']);

Thank you!

January 2, 2012 7:31 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Blanka: There shouldn't be a drop in pageviews, so that suggests a configuration issue. One possibility is that the _setDomainName code may be incompatible with some of the subdomains. For example, you might have mydomain.co.uk, or mydomain.someotherdomain.com. Also, if you have multiple levels of subdomains, such as sub1.sub2.mydomain.com, then you'll need to use .mydomain.com instead of mydomain.com. These types of situations all result in no pageviews being generated for the affected subdomain.

January 3, 2012 11:27 AM

Jens said:

Hi Jeremy,

Several days ago I submitted a comment. Since thena couple of other comments have been published, but not mine. Is there a chance my comment ended up in the spam list? I would be really interested to get your feedback on a couple of my questions...

Thanks, Jens

January 3, 2012 7:23 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Jens: I searched for your other comment, but I wasn't able to find it (not even in the spam list). If you wouldn't mind reposting your questions, I would be happy to answer them.

January 4, 2012 8:22 AM

AB said:

This is a very useful post.

A couple of questions:

We were previously using setdomain without a period before the domain name. When we adjusted the GA code for subdomain tracking we then ADDED a period inadvertently.

We noticed that both direct traffic and goal completions increased tremendously.

Is this because users were likely dually cookied and goal completions fired twice?

Thanks,

February 1, 2012 12:41 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@AB: I'm not sure why goal completions would go up, but switching from non-leading period to leading period causes a cookie reset, which results in an increase in direct traffic. Leading period and non-leading period cookies are completely incompatible; each destroys the other.

February 6, 2012 2:55 PM

AB said:

Paid traffic is also showing as direct. Would adding the leading period resolve this issue?

Thanks,

February 7, 2012 10:37 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@AB: Consistency is key. In most cases, it doesn't really matter whether or not you use the leading period, but it does matter that you do the same exact thing on every page of the site. If you have some pages with the leading period and some without, that will seriously affect tracking. Also, any other GA based script on the site needs to be consistent as well. For example, if you're running a GWO test on the site, the same modifications need to be made there as well, including urchin.js style modifications (i.e. _udn = ".example.com";). Sometimes third party scripts will include their own GA tracking, which typically needs to be disabled to avoid interfering with your own code.

Paid Traffic showing up as direct could also be a result of redirects stripping the tags or landing pages with missing or incorrect GA code. For AdWords, you also need to make sure that autotagging is enabled, that your Adwords and Analytics accounts are linked, and that cost data has been applied to all relevant profiles.

February 7, 2012 10:53 AM

Abhijeet Kotwal said:

Hi,

I have a website and a blog which I'm tracking using GA.

We are using following accounts to track the site and the blog (sub domain)

For the main website example.com: UA-1234567-1

For the blog.example.com: UA-1234567-2

The problem is currently, I have to see two separate GA reports and Google is treating Traffic separately.

What I need is, the traffic to the website and blog should be considered as a single source of traffic and
single Report where I can monitor Source, Audience, Content, etc.

P.S. The Website is hosted separately and blog is on WordPress.

Please suggest a solution.

Thanks
Abhijeet

February 9, 2012 4:05 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Abhijeet: You should change the code on the blog so that it uses UA-1234567-1 instead of UA-1234567-2. You'll also need to modify the code on both the blog and the main site for subdomain tracking. Usually this means adding a line of code immediately after the _gaq.push(['_setAccount', 'UA-1234567-1']); line that looks like this:

_gaq.push(['_setDomainName', 'example.com']);

The code may be different depending on the version of GA you have up on the site. If you're using a WordPress plugin for GA, there should be an option to specify the domain as "example.com". I believe it's called "Domain Tracking" under advanced settings.

February 9, 2012 8:48 AM

TW said:

First of all, thank you for this amazingly useful article. Good info is tough to find on this subdomain tracking topic.

My question: I am currently developing a new site (brand new) that will have upwards of 15 subdomains. Since a lot of your advice here deals with those who had previous (no leading period) setups, would you still recommend the no-leading-period setup to me even though I am starting new?

I'm simply trying to figure the best way to track all 15 subdomains in one profile while still able to differentiate between the subdomains in traffic reports.

Any advice is greatly appreciated - thanks!

February 9, 2012 11:56 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@TW: I still prefer no leading period for new setups as long as there aren't multiple levels of subdomains because it gives you a more forgiving setup. For example, a person may set up a Google Website Optimizer test on the site and forget to modify the code for subdomains. If you use the leading period, visitors who get entered into the test will likely have their cookies thoroughly thrashed, leading to invalid data in GA. If your site doesn't use the leading period, then while the GWO setup is not ideal, you have a greater chance of keeping your GA data intact. Similarly, if someone sets up another page or subdomain and forgets to add subdomain modifications to the tracking code, you're more likely to be OK if the rest of your site does not use the leading period than if it does.

As far as differentiating between subdomains in the traffic reports, you can do this for the most part using advanced filters. Advanced filters can let you see all the visits that touched a particular subdomain. It will also include pageviews from other subdomains if they were part of that visit.

If you need to distinguish between subdomains at the pageview level, then I would use an advanced filter to add a prefix to request uri indicating the subdomain. For example, you can set it up so that blog.example.com/index.html will show up in the reports as /blog/index.html. This can be done with a single advanced filter, or with multiple filters if you have longer subdomains that you want to shorten in the page-level reports.

February 9, 2012 12:25 PM

TW said:

Jeremy: Many thanks!

So, to make sure I understand your advice 100%, you're saying:

1) Set up tracking code on all 15 subdomains the same way:

//Tracking code customizations only
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-12345-1']);
_gaq.push(['_setDomainName', 'example-petstore.com']);
_gaq.push(['_addIgnoredRef', 'example-petstore.com']);
_gaq.push(['_trackPageview']);

2) Distinguish between subdomains at the pageview level through advanced filtering / custom reports

If you feel like giving me additional insight into the best way to set up that advanced filter, I'm all ears.

Thanks again!

February 9, 2012 3:55 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@TW: 1. Yes. 2. Advanced Segmentation and standard filters on the profile. The following is one way to set up the filters:

http://code.google.com/apis/analytics/docs/tracking/gaTrackingSite.html#profilesKey

February 10, 2012 8:28 AM

TW said:

Again: Many thanks!

February 10, 2012 2:50 PM

Abhijeet Kotwal said:

Hi,

Thank you very much for the help!

After your feedback I implemented the following code:

var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-1234567-1']);
_gaq.push(['_setDomainName', 'mydomain.com']);
_gaq.push(['_trackPageview']);
_gaq.push(['_setAllowAnchor', true]);

(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);
})();


I implemented this code for mydomain.com and blog.mydomain.com (both hosted seperately)

But after this code implementation the Bounce Rate has drastically jumped from 20%+ to 60%+... For most of the pages on mydomain.com existing pages.

Could you please tell me how do I fix this issue?


Thanks,
Abhijeet

February 13, 2012 11:33 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Abhijeet: Make sure you include _gaq.push(['_addIgnoredRef', 'mydomain.com']); as well. That's not likely the cause of the bounce rate increase, but it's worth adding regardless. It sounds like there may be some rogue code on the site that's no longer compatible with your main tracking code. You can use a tool like httpfox and see if more than one __utm.gif hit is being generated per page. If that doesn't turn anything up, check your browser reports and see if the bounce rate is affecting only one browser. If it's an IE issue, there are IE specific tools you can use to view hits and cookies to try to determine what's going on. If nothing else, it may be worth rolling back the code temporarily until you can determine what's going wrong in a test environment.

February 14, 2012 8:22 AM

Domenico said:

Hi Jeremy,

thanks for this great article.

I have got an issue: I have got an existing main domain (say example.com) which has been collecting data for a couple of years and I now need to set up a third level domain (say something.example.com) within the same UA. I've followed your instructions as far as the third level domain is concerned so the code looks like

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

and set up a brand new profile under Google Analytics with a filter as "Include only traffic from the domains that are equal to something.example.com"

I have modified the tracking on the main domain site as follows

_gaq.push(['_setAccount', 'UA-XXXX-Y']);
_gaq.push(['_setDomainName', 'example.com']);
_gaq.push(['_addIgnoredRef', 'example.com']);
if(condition == true)
{
_gaq.push(['_setCustomVar', 1, 'CustomVarName', CustomVarValue, 2]); // I need this for some special situations
}
_gaq.push(['_trackPageview']);

but the main domain tracking has immediately dropped to 0, while on the second profile has not been collected at all.

What have I done wrong?

Thanks,
Domenico

March 14, 2012 10:53 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Domenico: I don't see anything wrong with the code you've set up. The behavior sounds like there may be an issue with the domain string you're passing to _setDomainName. If this string does not match the root level domain, then your tracking won't work at all. This could be a typo, or perhaps using .net instead of .com or something along those lines. Also note that while with _addIgnoredRef you could pass just 'example' instead of 'example.com' without any ill-effects, the same is not true of _setDomainName.

As far as the filter is concerned, I generally don't trust any of the pre-built filters, but always use a custom filter with the correct regex. In this case, I'd use a custom include filter on the hostname field with a value of "^something\.example\.com$".

March 14, 2012 11:47 AM

Domenico said:

Unfortunately there was no typo and everything seemed correctly set up, at least to me.

I'll give it another try and hope..

Anyway, thanks for your help.
Domenico

March 14, 2012 1:33 PM

Matt said:

Jeremy,

Great post and seriously impressive that you've responded to every commenter! So here's another one: after implementing this code a few months ago I've reduced the amount of self referrers by about 97% BUT I'm still seeing enough to believe that something still needs to be tweaked. First question, can you every totally eliminate self referrers? Second, based on this code do you see any obvious problems or have any suggestions:

I have a www.domain.com and info.domain.com. Code is the same on both:


try { var pageTracker = _gat._getTracker("UA-1234567-1");
pageTracker._setDomainName("domain.com");
pageTracker._trackPageview();
var supplementalTracker = _gat._getTracker('UA-1234567-2'); supplementalTracker._trackPageview();
} catch (err) { }


notice that I'm also pushing data into a second profile as per a client's request. Finally I didn't use addIgnoredRef and if you think that's the solution please let me know.

Thanks

March 30, 2012 11:59 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Matt: I would use _setDomainName("domain.com") for supplementalTracker as well and use _addIgnoredRef("domain.com") for both. That should take care of any lingering self-referral issues.

I think it's possible, but very difficult, to eliminate all self-referrals. If there are a few lingering self-referrals that make up less than 1% of your overall traffic, especially if also less than 1% of key visits (e.g. converting visits), then it's probably not worth chasing down the remaining fraction of a percent. For complex sites, the bar may be higher than 1%.

March 30, 2012 1:01 PM

Matt said:

Thanks Jeremy! Can you provide some reasons why it may be impossible to remove all self-referrals. The only reason I can think of is old cookies from pre-cross domain tracking modification Visitors.

March 30, 2012 2:15 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Matt: That's one reason. Other reasons include cached pages or pages with old/rogue code.

March 30, 2012 3:22 PM

Maggie said:

Hi Jeremy,

Using your article, we recently updated our GA tracking code to the following:
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-111111-1']);
_gaq.push(['_setDomainName', '.domain.com']);
_gaq.push(['_addIgnoredRef', 'domain.com']);
_gaq.push(['_trackPageview']);

Now we need to implement cross-domain tracking as well. Should we just add the _gaq.push(['_setAllowLinker', true]); line, or we should remove the _addIgnoredRef?

April 5, 2012 7:29 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Maggie: Just add the _gaq.push(['_setAllowLinker', true]); line.

April 5, 2012 8:07 AM

Newbie said:

Hi Jeremy,

Thanks for the great article, it's quite a puzzle getting your head around all these settings to be honest. I'm currently reviewing a proposed implementation (below) which requires the referral data between subdomains to be captured in a separate account for each subdomain and the cross domain data to be captured in one overall account. Do you see any reason why this wouldn't work?


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



_gaq.push(['._setAccount', 'UA-xxxxxxx-1']);
_gaq.push(['._setDomainName', '.domain.com']);
_gaq.push(['._trackPageview']);

April 23, 2012 11:39 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

In order for this work, your main domain must resolve all requests to www.domain.com. If it can resolve/does resolve to just domain.com instead, then you will have cookie conflicts for those pages.

I would also recommend using the following instead:

var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-xxxxxxx-1']);
_gaq.push(['_setDomainName', document.domain]);
_gaq.push(['_trackPageview']);



_gaq.push(['._setAccount', 'UA-xxxxxxx-1']);
_gaq.push(['._setDomainName', '.domain.com']);
_gaq.push(['._trackPageview']);

Passing document.domain set cookies to fully qualified domain name without turning off cookie hashing. Passing 'none' also sets cookies to the fully qualified domain name, but it turns off hashing too. The hash allows the the code to determine the correct set of cookies to read from. When it's turned off, the code will read the first set of cookies it finds, which may be the wrong set.

Also, if you don't have any lower-level subdomains (e.g. my.sub.domain.com), and don't expect to have any, then you should use 'domain.com' instead of '.domain.com' This will make your code a bit more resilient if, say, someone puts some rogue code on the site or launches a Google Website Optimizer test.

April 23, 2012 12:19 PM

Jackye said:

Hi Jeremy..
It's so hard to make that works.
We have 2 sub-domains here, and when I put:

_gaq.push(['_setDomainName', '.example-petstore.com']);
_gaq.push(['_setAllowHash', false]);

It get a lot of self referrals. =/
But I didn't understand your suggestion quite sure..
So How can i do it?
Something like that:

_gaq.push(['_setDomainName', 'domain.com']);
_gaq.push(['_addIgnoredRef', 'domain.com']);
_gaq.push(['_trackPageview']);


What will happen with sub1.domain.com and sub2.domain.com? Should I put the same code? Or do I need to put a change on them too?

Thank you so much, these settings are so hard to understand =/

April 26, 2012 4:09 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Jackye: Yes, the code you posted should work:

_gaq.push(['_setDomainName', 'domain.com']);
_gaq.push(['_addIgnoredRef', 'domain.com']);
_gaq.push(['_trackPageview']);

You would use this same code on both sub1.domain.com and sub2.domain.com.

April 26, 2012 4:55 PM

Jackye said:

Thanks!

Another quick one:

Is there any really difference between this:

_gaq.push(['_setDomainName', '.domain.com']);
_gaq.push(['_addIgnoredRef', '.domain.com']);
_gaq.push(['_trackPageview']);

and this:

_gaq.push(['_setDomainName', 'domain.com']);
_gaq.push(['_addIgnoredRef', 'domain.com']);
_gaq.push(['_trackPageview']);

the "." before domain.com really matters?
our domain here is www.domain.com with subdomains: sub1.domain.com and sub2.domain.com

Thanks again!

April 27, 2012 8:51 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Jackye: Yes, there is a difference. If you use the leading period (the "." before domain.com), then your cookies will be set in such a way that they'll be accessible to lower level subdomains (e.g. lowersub1.sub1.domain.com). Most people do not have lower level subdomains, so this is usually unnecessary. Furthermore, cookies set without the leading period are more compatible with cookies set without any subdomain at all.

So if you have the option to not use the leading period, this is usually the way to go as it makes your code more resilient. For example, someone might launch a Google Website Optimizer test on the page without adding subdomain code, or you might use a 3rd party plugin that also happens to have Google Analytics tracking enable. With these types of situations, there's a greater chance that your tracking will be just fine if you don't use the leading period. Otherwise, both of these scenarios would result in a cookie conflict, with the end result being that your cookies would be destroyed and recreated with incorrect referral information.

For _addIgnoredRef, you should not use the leading period regardless of whether or not you use the leading period for _setDomainName. _addIgnoredRef does a straightforward string comparison between the current domain and the string you pass to it. So if someone can get to, say, domain.com without the www, then _addIgnoredRef won't catch it if it has the leading period. You can, in fact, simplify _addIgnored ref and just pass "domain" if you felt like it. Of course, this would potentially ignore domain.org or domain.net as well, but it's really just to illustrate the fact that _addIgnoredRef just checks to see if the string passed to it is a substring of the current domain.

April 27, 2012 9:35 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Jackye: Yes, there is a difference. If you use the leading period (the "." before domain.com), then your cookies will be set in such a way that they'll be accessible to lower level subdomains (e.g. lowersub1.sub1.domain.com). Most people do not have lower level subdomains, so this is usually unnecessary. Furthermore, cookies set without the leading period are more compatible with cookies set without any subdomain at all.

So if you have the option to not use the leading period, this is usually the way to go as it makes your code more resilient. For example, someone might launch a Google Website Optimizer test on the page without adding subdomain code, or you might use a 3rd party plugin that also happens to have Google Analytics tracking enable. With these types of situations, there's a greater chance that your tracking will be just fine if you don't use the leading period. Otherwise, both of these scenarios would result in a cookie conflict, with the end result being that your cookies would be destroyed and recreated with incorrect referral information.

For _addIgnoredRef, you should not use the leading period regardless of whether or not you use the leading period for _setDomainName. _addIgnoredRef does a straightforward string comparison between the current domain and the string you pass to it. So if someone can get to, say, domain.com without the www, then _addIgnoredRef won't catch it if it has the leading period. You can, in fact, simplify _addIgnored ref and just pass "domain" if you felt like it. Of course, this would potentially ignore domain.org or domain.net as well, but it's really just to illustrate the fact that _addIgnoredRef just checks to see if the string passed to it is a substring of the current domain.

April 27, 2012 9:35 AM

Rita said:

I'm trying to understand this (eek) and set up my GA. I have a .com site such as: www.bookstore.com and on that same domain have added www.bookstore.com/blog. (wordpress) What I don't understand is; is the blog considered the subdomain? And would I put the .com site as the domain and leave the blog as the subdomain? Or would I put the .com/blog and leave the main .com as the subdomain ? Then, what exact code would I add to the generated code so that it would all track properly ? Thanks for keeping it simple. :)

June 1, 2012 12:44 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Rita: What you have is a subdirectory. There's no special code needed in order to track your subdirectory in addition to your main site. The standard GA code should work fine.

If your wordpress blog was on blog.bookstore.com, instead of www.bookstore.com/blog, then you would have a subdomain and would need to modify your code.

June 1, 2012 1:21 PM

Rita said:

@Jeremy, okay my website is a eg. www.bookstore.com and my blog is www.bookstore.com/blog so you said that would make it a subdirectory and no need to update the code. Good. So, my question is; what do I put in the profile settings URL and the property settings URL would I only ever need to put eg; www.bookstore.com and then the .com/blog part would automatically pick up in the stats ? So, should property and profile URL's match ? That is what I need to know to finish signing up with my proper settings. Thanks so much!

June 3, 2012 1:22 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

GA does not consider a subdirectory to be a separate site, even if the hosting for that subdirectory is different for the rest of your site. It will pick up on your subdirectory automatically. If you decide to create a profile that only reports on your blog subdirectory, you will need to add a filter to that new profile to only include traffic to that subdirectory. The profile name should probably include the subdirectory as well, only to be able to distinguish it from your main profile, but the subdirectory does not need to be included as part of the URL, and you should not create a new web property for the subdirectory, but rather use the existing web property for your main site.

June 4, 2012 8:50 AM

Nathan Arthur said:

Hello, Jeremy!

I've got a question for you: Will subdomain tracking work when the main domain and the subdomain use different versions of the GA tracking code? I'm using an eCommerce service (store.mydomain.com) which uses legacy ga tracking code, whereas my main site (mydomain.com) uses the new asynchronous version.

The problem I'm trying to fix is that any traffic that came from my main site, to the store, and then ended in a purchase, shows as direct traffic. The original referral data isn't being preserved.

My modified code looks like this:

mydomain.com/.org code:

var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-xxxxxxx-y']);
_gaq.push(['_setDomainName', 'mydomain.com']);
_gaq.push(['_addIgnoredRef', 'mydomain.com']);
_gaq.push(['_addIgnoredRef', 'mydomain.org']);
_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);
})();

store.mydomain.com code:

var pageTracker = _gat._getTracker('UA-xxxxxxx-y');
pageTracker._addDevId('o5cUG');
pageTracker._setAllowLinker(true);
pageTracker._setDomainName('none');
try{pageTracker._setDomainName('mydomain.com');
pageTracker._addIgnoredRef('mydomain.com');
pageTracker._addIgnoredRef('mydomain.org');}catch(e){};
pageTracker._trackPageview();

What am I doing wrong?

June 14, 2012 2:21 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Nathan: You can use different versions of the GA tracking code on different pages. The issue you're having is that visitors are going from a .org site to a .com site. This is a cross-domain situation, which means that you'll need to modify your code for cross domain tracking:

https://developers.google.com/analytics/devguides/collection/gajs/gaTrackingSite

More specifically, you should not have both _setDomainName('none') and _setDomainName('mydomain.com'). I would use the latter on both mydomain.com and store.mydomain.com, and use _setDomainName('mydomain.org') on mydomain.org. You should also include _setAllowLinker('true') on all three sites and make sure to use _link or _linkByPost as appropriate on any links or forms that go from .org to .com or vice versa.

June 15, 2012 8:30 AM

Nathan Arthur said:

Thank you so much for the reply!

So .org is just an alias of our .com address. Anything available on the .com is available on the .org. Is there a way to make Google Analytics play nice with this, and not have to worry about tracking then like they were two different sites? Would using only "_setDomainName('mydomain.com');" achieve that?

I would really like to avoid having to worry about cross-domain tracking if at all possible. We've even thrown around the idea of just setting up a site-wide 301 redirect from .org to .com if it would take the cross-domain aspect out of the picture. I'd rather not have to resort to that, though.

June 18, 2012 8:59 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Nathan: 301 redirecting from .org to .com would avoid the cross-domain situation. Alternatively, you could also have a store.mydomain.org in addition to store.mydomain.com. Then you would just need to be consistent with your links and maintain separate tracking codes for the .org and .com sites, since the _setDomainName line would be different for the .org and the .com sites.

There are also scripts which can be used to tag all of the links going between the two domains. It's still considered cross-domain, but it can take some of the pain out of the setup. It's also not too hard to write your own script, especially if you already have a JavaScript library like jQuery on the site. The trickest part is getting such scripts to work for edge cases such as links and forms with multiple redirects and things like that. If you have full control over all sites, then you may be able to eliminate those types of situations if any exist, which can greatly simplify cross-domain tracking.

June 19, 2012 8:06 AM

Stuti said:

Thank you so much for this.
Made my day
God bless you :)

July 30, 2012 1:55 PM

vincent said:

hi Jeremy:

i have also encounted the self-referral issue, and should it add the the modify code "_gaq.push(['_addIgnoredRef', 'sister-site.com']);" to all pages in each subdomain? or add only one statement in the front page

November 2, 2012 11:16 PM

vincent said:

hi jeremy

i also have the self-referral issue, and i followed your instrcution adding the modified code :"_gaq.push(['_addIgnoredRef', 'sister-site.com']);"
in each pages of our maindomain. but the problem still exist.

should i add the modified code for each pages under each subdomain? or just add only a statement on the front page of our main domain?

as u menetioned in our article :"This also eliminates the need to add a separate _addIgnoredRef statement for each subdomain."

so confused..

November 3, 2012 12:00 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@vincent: You should add the same modification to all subdomains as well.

There is a common misconception that you need to add a separate _addIgnoredRef statement for each subdomain:

// BAD EXAMPLE
_gaq.push(['_addIgnoredRef', 'www.sister-site.com']);
_gaq.push(['_addIgnoredRef', 'blog.sister-site.com']);
_gaq.push(['_addIgnoredRef', 'shop.sister-site.com']);

Instead, only one line is necessary site-wide, regardless of how many subdomains you have:

// GOOD EXAMPLE
_gaq.push(['_addIgnoredRef', 'sister-site.com']);

Note also that the official documentation still recommends:

// BAD EXAMPLE
_gaq.push(['_addIgnoredRef', 'www.sister-site.com']);

which is still wrong since it won't match requests for your domain without the 'www', nor for subdomains.

November 5, 2012 7:55 AM

Jasmina said:

Hello

I want to track www.example.com and not other subdomains, e.g. static.example.com. To that effect I've tried setting _gaq.push(['_setDomainName', 'www.example.com']); but this is not working out as the cookie is still set to example.com so it's also set for static.example.com

How would you recommend that this is implemented so that the cookie is only set for www.example.com and not for static.example.com or any other subdomain?

301 redirect is in place for example.com to www.example.com

November 7, 2012 6:23 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Jasmina: The line you're adding should work, so if you're having trouble with it, make sure you're adding it after the _setAccount line but before the _trackPageview line.

November 8, 2012 7:51 AM

Jasmina said:

Ta Jeremy, it became obvious as soon as I read your comment.

November 8, 2012 4:27 PM

Poulpator said:

Hi,
I have more than 200 subdomain.
And a need to know each unique visitor per subdomain.
Is there a way to view data per subdomain without creating a profile for each subdomain?

Regards from French Alps

November 20, 2012 11:36 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Poulpator: You can set up a custom report with Hostname as a dimension and unique visitors as a metric.

November 20, 2012 3:29 PM

Chris Eldredge said:

are any recommendations in this article now out of date?

thanks for the great article!

May 21, 2013 4:34 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

The code modifications recommended by this article for subdomain tracking are still up to date for ga.js.

May 22, 2013 8:09 AM

Pavel said:

Jeremy, sorry if this has already been answered before, but I couldn't find it in the 3 years of comments to this topic, so would appreciate if you could help me out.
We have a website with 3 language versions.
www.website.com for english
lang1.website.com for lang 1
lang2.website.com for lang 2

Currently we have a default tracking code installed which results in inflated visits, recorded under Referral section of google analytics.

Do we understand this correctly that adding
_gaq.push(['_addIgnoredRef', 'website.com']);
would eliminate those self-referrals?

So if originally the user came from Google to a www-version and then switched to lang1., then with the updated tracking code, Google Analytics would report that visit as a single visit originating from Google but would include two Domain Names under this visit which were visited by the user.

Hmmm, but then, that would be two visits, no?

Do you know, how would such a visit be reflected in the GA-report?

December 6, 2013 12:03 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Pavel: Assuming you're still using ga.js analytics, you will need both lines:

_gaq.push(['_setDomainName', 'website.com']);
_gaq.push(['_addIgnoredRef', 'website.com']);

December 9, 2013 12:42 PM

anna-lisa said:

Hi Jeremy, thanks for your helpful post. I have a question: I have a cross domain & subdomain issue, site A with subdomain A1/A2/A3 and so on, and the conversion/transaction occurs on Site B. I have set a duplicated complete profile for all visits to site A with a filter which includes all visits coming from subdomains. Then I have set single profiles for each subdomain with a filter including visits from each subdomain (filter Host name). On these single profiles I can't see any conversion/transaction. I presume it's because the filter includes only visits from subdomain, so visits (and conversions) from Site B are excluded.

Am I right? Is there a way to solve this problem?

February 28, 2014 5:38 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

If you track all of the domains and sub domains in a single view/profile, then you should be able to create custom advanced segments for each subdomain. Any filter solution would likely require a complicated set of 3 filters based on an indicator on Site B that lets you know which sub domain it's currently being used for.

March 3, 2014 9:04 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

If you track all of the domains and sub domains in a single view/profile, then you should be able to create custom advanced segments for each subdomain. Any filter solution would likely require a complicated set of 3 filters based on an indicator on Site B that lets you know which sub domain it's currently being used for.

March 3, 2014 9:04 AM

Damion said:

Brilliant! I just wish this post was written..... er, the last time I needed to have this as a reference! I had to cobble together a fix from those various inadequate, outdated, fuzzy articles you mention.

I've bookmarked this, and hopefully I'll remember its existence next time the sound of dying tracking is all around. Devs all too often give little thought to how tracking might be affected by their "quirky" subdomain (or even multi-domain) structure, and I'm hoping that this article might be able to solve a few problems before they spiral out of control. Thanks once again!

January 5, 2011 5:13 PM

Eric Polatty said:

If you go to the tracking code section under profile settings in your GA account, and click "one domain with multiple subodmains" under "what are you tracking", I notice the code Google generates for you to use does not include the _setAllowHash tag. But they tell you to include it in the Google Code article for subdomain tracking. I understand it's a free product - but I find Google's inability to make up their minds about how to use their own software frustrating to say the least.

January 6, 2011 9:51 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Eric: My guess is that the Google Code example includes _setAllowHash because it is on a page dedicated to cross-domain tracking. Unfortunately there's currently no Google Code page that just deals with subdomain tracking. I think we lost this during the transition from the traditional ga.js code to the async code, but I'm hopeful that this will be addressed.

The code that's generated from your Google Analytics account is better, but still suffers from the other issues I went over. The lack of an _addIgnoredRef line, or rather the lack of the logic behind the _addIgnoredRef line being executed for an appropriate _setDomainName call, is especially disconcerting since it implies that _setDomainName is sufficient for optimum subdomain tracking.

January 6, 2011 10:37 AM

Eric Polatty said:

@Jeremy - Most of the main Google Code article is on cross-domain situations, but there is a section "tracking across a domain and it's sudomains" and it has the _setAllowHash tag there.

January 7, 2011 10:26 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Eric: It's possible that since it was sandwiched between the other cross-domain examples that the _setAllowHash tag was added unintentionally. Regardless, it shouldn't be there for a subdomain only example.

January 7, 2011 10:32 AM

Mike Sullivan said:

Thank you! Thank you! Thank you!

We added (yet another) subdomain to our environment over the holidays and I tried (yet again) to get rid of the self-referrals. There's so much not-quite-right guidance out there!

Made your suggested changes and today, they have dropped WAY off!

January 7, 2011 11:50 AM

Adam said:

Great article. I'd just about given up on solving the self referrals issue.

Question: if your site uses both subdomains and lower level subdomains, should you use a leading period on both, or just your lower level subdomain pages?

January 7, 2011 12:05 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Adam: If your site has lower level subdomains, then you should use the leading period site-wide.

If you used the leading period on some subdomains and not on others, the hash codes for the cookies would be different, so your cookies would get destroyed every time you crossed from a page using the leading period to a page not using the leading period and vice versa. So regardless of whether you decide/need to use the leading period or not, you want to be consistent.

January 7, 2011 2:09 PM

david said:

Hi Jeremy,

This article of yours was definitely a nice reading.

I experienced myself lots of issues a few weeks ago when adding subdomain tracking to our site, following Google instructions. One of the main problems was a huge boost of direct traffic (we were using leading period, but we didnt use SetAllowHash).

I am willing to try your solution now. However, would you still recommend this implementation (no period and AddIgnoreRef) even for the traditional ga.js code?

January 10, 2011 7:20 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@David: Yes, I would recommend this solution even if you're using the traditional ga.js code. This would look something like the following:

var pageTracker = _gat._getTracker("UA-12345-1");
pageTracker._setDomainName("example-petstore.com");
pageTracker._addIgnoredRef("example-petstore.com");
pageTracker._trackPageview();

A sudden influx of direct traffic can result from going from no subdomain tracking to subdomain tracking with the leading period. Removing the leading period may help, but this depends on how long you've had the code with the leading period up. There aren't any hard or fast rules on this, but I would say that if you've only had the code with the leading period up for a month or more, you might be better off sticking with it at this point.

There's nothing inherently wrong with using the leading period. The main issue I have with it is that for a site that the hash code generated when you use the leading period is different than the one generated when you don't have subdomain tracking at all. If you've already been using the leading period for a significant amount of time, then switching your code to not use the leading period may be just as bad for tracking as switching to using the leading period in the first place.

Also, for a brand new Google Analytics installation, using the leading period is perfectly fine.

January 10, 2011 8:02 AM

David said:

Thanks for your advice, Jeremy. I will keep your considerations in mind and try your proposed subdomain tracking code.

We had the code with the leading period for just a couple of days. The breakage of the data was big enough to get quickly back to the older version, even though it was not taking into account the existing subdomains.

Hopefully I will get a chance to try your suggestions some day next week. Our site has a large amount of traffic, so after a few hours we will be ready to say if it is working or not. I will let you know ;)

January 10, 2011 10:19 AM

Cloga said:

Excellence article!Thank you!

January 10, 2011 10:46 AM

Cristina Chetroi said:

Hi Jeremy!
The _addIgnoredRef tip to minimise self-referrals is great, as they really are a pain. Thanks!

I also remember someone mentioning the inconsistency between the code GA console generates for subdomain tracking (no setAllowHash to false) and the official documentation.

We all wish domain hashing needn't be compromised. But the reality is that it often is - it's common that a client decides to introduce subdomains or other domains at a later stage and you need to tweak the snippet as the result.

So, when it happens, would it be possible to introduce some sort of cookie checkup for returning visitors and do some sort of merge instead of setting a second set cookies/destroying them?

January 12, 2011 5:19 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Cristina: It would certainly be possible to do that. I've done something similar to that before with cookies that were generated with _setNamespace, so it shouldn't be that hard. I have some other ideas about how this might be done as well, something I'm hoping to write about in a future post.

January 13, 2011 7:54 AM

Liz said:

would i use this customization on all subdomains and the top level domains? Or just all the subdomains I want to track - I will have about 4 or 5 of them.

Thanks

January 27, 2011 2:27 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Liz: I would recommend using the modification on all subdomains and top level domains. I have seen some cases where people wanted to track certain subdomains only so they could see traffic coming from other subdomains as referrals, but this is not an ideal setup. Inevitably someone also wants to track the other subdomains, which gives you strange mix of referrals from subdomains and original referral data to those subdomains showing up in your reports. Instead, you should track everything and use filters in Google Analytics to exclude the unwanted domains.

January 27, 2011 4:26 PM

Bernd said:

You wrote:
_gaq.push(['_setDomainName', 'example-petstore.com']);

Google says:
_gaq.push(['_setDomainName', '.example-petstore.com']);

(see the dot before domainname).

What is the difference?

January 30, 2011 2:16 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Bernd: The main differences are that:

1. Each generates a different hash, but not including a leading period has the same hash as no subdomain tracking at all.
2. Including a leading period works for sites with lower level subdomains (ex. buy.store.example-petstore.com).

Google includes the leading period to account for #2. The reason I don't include the leading period is because of #1. It feel that it's more likely that someone is transitioning their code from no subdomain tracking to subdomain tracking than that they have lower level subdomains.

So, as mentioned in the article, if you have lower level subdomains, or if you're setting up Google Analytics Tracking Code on your site for the first time, use the leading period. If you don't have lower level subdomains and you've had Google Analytics Tracking Code on your site for a while, then don't use the leading period.

January 31, 2011 7:54 AM

Bernd said:

OK, thank you very much, Jeremy!

January 31, 2011 1:33 PM

Nick said:

I'm a little confused. Your second point says that you have to use the leading period if you have lower level subdomains, but then at the end you said don't use if you don't have to.

Let's say I have example.com and store.example.com, would I want to use the leading period to track this properly?

January 31, 2011 5:52 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Nick: The only time you have to use the leading period is if you have lower level subdomains. For your example, the leading period is unnecessary for tracking this properly because you don't have any lower level subdomains. You'd have to have another level of subdomain tacked on to there, such as buy.store.example.com.

If you don't have lower level subdomains and you're setting up Google Analytics for the first time on a site, then you have the option to either use or not use the leading period. I tend to not use it as this tends to be more stable, again because the hash code is the same as if you didn't have subdomain tracking on the main domain. So if someone else sets up a Google Website Optimizer test on your homepage, for example, and forgets to add subdomain tracking modifications, this isn't as big of a deal if you had implemented subdomain tracking without the leading period.

The main benefit to using the leading period for new sites without lower level subdomains is that you'll have less people question your setup since it's closer to the Google recommendations.

For sites with existing Google Analytics Tracking Code that you want to update to use subdomain tracking code, not using the leading period will lead to a much smoother transition. Of course, if your site also has lower level subdomain, you'll have to bite the bullet and use the leading period anyway.

Whichever way you decide to go, make sure that you apply that decision consistently across your site. Having some pages that use the leading period and some that don't will wreak havoc on your site.

February 1, 2011 7:56 AM

Chris said:

I'm working on a WordPress MultiSite project which uses subdomain, some of which are mapped to other domains. So what I'm doing really is more in line with the Google example since its not just sub-domain tracking but cross-domain tracking. My question to you is is there any benefit to using _addIgnoredRef for cross-domain tracking? Or could it hurt in any way? I'm looking to reduce self referals as much as possible.

February 4, 2011 12:21 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Chris: Using _addIgnoredRef will still help some with preventing self-referrals. You should have one _addIgnoredRef statement for each root level domain. _addIgnoredRef only ignores a referral if there is previous referral data to fall back on.

So if you have any links between domains that aren't tagged with the proper linking parameters, this will show up in your reports as self-referrals, even if you use _addIgnoredRef. This is a good thing, because it provides visibility for fixable self-referrals.

If there is previous referral data, however, _addIgnoredRef will preserve it. This can be especially useful in situations where you can tag links to a third-party domain, but have trouble tagging links going back to the original domain.

February 4, 2011 8:33 AM

Rob said:

I tried using Google's subdomain tracking suggestion to no avail. For 1 day I did see in GA URL's from the subdomain but I have not been able to figure out how. I came upon this blog after discussing this with a GA expert who has been gracious enough to help us try a few options.

So I adjusted the subdomain code to look like this, per your suggestions:

var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-xxxxxxx-y']);
_gaq.push(['_setDomainName', 'cae-nyc.org']);
_gaq.push(['_addIgnoredRef', 'cae-nyc.org']);
_gaq.push(['_trackPageview']);


The primary/main Drupal-driven domain has this:


var _gaq = _gaq || [];
_gaq.push(["_setAccount", "UA-xxxxxxx-y"]);
_gaq.push(['_setDomainName', 'cae-nyc.org']);
_gaq.push(['_addIgnoredRef', 'cae-nyc.org']);
_gaq.push(["_trackPageview"]);

Now, a thing to note: we have 2 URL's that we use, hosted on a share GoDaddy account: caenyc.org and cae-nyc.org. (Notice a hyphen). The subdomain does NOT have a hyphen it' all advocacy.caenyc.org. I do not have access to an Apache httpd.conf file so I have to use GoDaddy's GUI/Total Domain Control to create the redirect. Could that be causing the problem? Can you peak at both domains & view their source?

Thanks!

Rob

February 8, 2011 9:44 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Rob: Your code should be different depending on which domain it's on. So on cae-nyc.org (with the hyphen), your code should look like the following:

var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-xxxxxxx-y']);
_gaq.push(['_setDomainName', 'cae-nyc.org']);
_gaq.push(['_addIgnoredRef', 'cae-nyc.org']);
_gaq.push(['_trackPageview']);

But on caenyc.org (without the hyphen), your code should look like the following:

var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-xxxxxxx-y']);
_gaq.push(['_setDomainName', 'caenyc.org']);
_gaq.push(['_addIgnoredRef', 'caenyc.org']);
_gaq.push(['_trackPageview']);

The value you pass to _setDomainName must match the domain it's on, otherwise the code will fail. This is also true when you're tracking both example.com and example.net.

I also don't know if visitors can go back and forth between cae-nyc.org and caenyc.org. If they can, then that falls under the realm of cross-domain tracking, which requires a completely different set of tracking code modifications. Still, you'll need to fix the _setDomainName line on caenyc.org to get any kind of tracking there at all.

February 8, 2011 1:03 PM

Rob said:

Sigh, I wish I had tried the obvious yep that worked. And yes people can go from the sub-domain to the main domain and vice verse.

So for example, an email campaign might start with the sub-domain. Then a person fills out the form on the sub-domain, and clicks on Home, which goes back to the main www domain.

Or, people will click on a link from www, e.g., on the home page, and go to the sub-domain, fill out the form, and may hit home. Does that mean cross-domain?

Also, using the sub-domain filter, the Content report is showing the paths with a leading / like this:

/advocacy.caenyc.org/site/apps/kb/cs/contactsearch.asp

or

/advocacy.caenyc.org/site/c.rwL4JlO7KzE/b.6421085/k.DF6F/Petition_to_Incoming_Schools_Chancellor_Cathie_Black/apps/ka/ct/contactus.asp?c=rwL4JlO7KzE&b=6421085&en=ftINKXMILiKPJ5PUJeILI3OLInKZI7OKJgIXK6OQKtK9F


I take it I can transform the URL with another filter?

February 8, 2011 4:53 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Rob: You only need to implement cross-domain tracking if a visitor can move across root level domains. Going from avocacy.caenyc.org to www.caenyc.org does not count as cross-domain because you're just moving from one subdomain of caenyc.org to another.

Going from avocacy.caenyc.org to www.cae-nyc.org, however, does count as cross-domain tracking and requires additional modifications to your code, as well as modifications to the links going between domains. Generally it's something to be avoided if at all possible.

In your situation, the easiest way to avoid the issue is to just 301 redirect visitors who request cae-nyc.org pages to the appropriate caenyc.org page. This eliminates the need for cross-domain tracking and dramatically simplifies your Google Analytics setup.

With regard to filters, yes, you can apply additional filters after the subdomain filter. Those filters will be applied to the modified URL instead of the original URL, so you can use this to change the URL to look exactly how you want it to in Google Analytics. Also, you may want to look at Exclude URL Query Parameters under the Main Website Profile Information to remove any unnecessary query parameters and clean up reporting even further. This is usually easier than using filters to remove the query parameters.

February 9, 2011 7:57 AM

Emily said:

I have multiple domains that I have the same UA# (cookmedical.com, cookbiodesign.com and cookartlab.com). These domains feed traffic between each other and so it would be helpful if I could track them as if they were all the same site to track users between the domains. Based on this information it sounds like I should add the following to all of the pages in all the domains:

_gaq.push(['_setDomainName', 'none']);
_gaq.push(['_addIgnoredRef', 'cookmedical.com']);
_gaq.push(['_addIgnoredRef', 'cookbiodesign.com']);
_gaq.push(['_addIgnoredRef', 'cookartlab.com']);

Am I understanding you correctly?

February 9, 2011 8:48 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Emily: The _addIgnoredRef lines may help with some self-referrals issues, but they're not directly related to cross-domain tracking.

Cross-domain tracking in Google Analytics is the sort of thing that really deserves a series of posts, but I'll try to summarize it as best as I can within this comment.

First, I generally avoid using _gaq.push(['_setDomainName', 'none']); because it does too much. _gaq.push(['_setAllowHash', false]); (no quotes around false) accomplishes the minimum for cross-domain tracking, so it's preferred.

Second, you'll also need to add _gaq.push(['_setAllowLinker', true]); (again, no quotes around true).

Third, you'll need to modify the links between domains. The easiest way to do this is to have the following onclick attribute in the link:

onclick="_gaq.push(['_link', this.href]); return false;"

This covers most scenarios, but not all of them. There will likely be additional nuances that these instructions won't handle. The official Google Code article may help with some of these.

Here are some other things to keep in mind:

1. _link invokes a javascript redirect, which means the referrer won't be available on the receiving page in IE. There are other ways to do this that preserve the referrer, but they are more advanced.
2. _linkByPost may work with forms that use GET instead of POST, but you'll have to specifiy true in the third parameter, that is:

_gaq.push(['_linkByPost', this, true]);

This passes query parameters through the anchor text instead of the query string. This means you'll also need to add _gaq.push(['_setAllowAnchor', true]); to your Google Analytics Tracking Code.
3. It's generally preferred to accomplish linking between domains in a more dynamic way. You might be able to build this into a template driven site, or use a script that modifies onclick attributes of links dynamically.
4. You should try to minimize redirects between domains. These will often do unintended things to query parameters and anchor text and make cross-domain tracking very difficult or impossible.

Because of all the complications involved in cross-domain tracking, you may want to consider purchasing a support plan to ensure that everything is set up correctly.

February 9, 2011 9:18 AM

Emily said:

Thanks that helps a lot. I talked to my developer about this and we're building a dynamic script to add the onClick function to the links that are moving between domains that we want to track together.
I agree that it would be best if we didn't have this highly related content on different domains and we are in the process of redesigning our overall site to include the pages that are currently on separate domains. In the mean time we really need to be able to see how users are moving through our sites.

Thank you for all your help!

February 9, 2011 10:44 AM

Eduardo Cereto said:

The argument that the leading dot can cause problems when you're changing a GA implementation is valid. But what's not clear in the post is your opinion about new implementations.

Since a new implementation doesn't have any already set cookie we should bother, than I think there's no drawback about using the leading dot.

I always use the leading dot in my new implementation, and will keep doing so.

I'm not only worried about the sub-sub-domains. But the leading dot feels more compliant with the RFC that specifies that the absence of it can cause Rejection of the cookie. I'm not sure how many browsers acctually comply to that statements, none I know of. Still I'd rather not take my chances.

http://www.ietf.org/rfc/rfc2109.txt

Quoting the RFC:
4.3.2 Rejecting Cookies
...
* The value for the Domain attribute contains no embedded dots or
does not start with a dot.

[page] 4
Domain=domain
Optional. The Domain attribute specifies the domain for which the
cookie is valid. An explicitly specified domain must always start
with a dot.

February 10, 2011 10:32 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Eduardo: I think that you can argue it either way for new Google Analytics implementations. I prefer not to use the leading period even for leading implementations (assuming of course that there aren't any sub-sub-domains). The reason is that this type of setup tends to be more forgiving when it comes to things such as rogue Google Website Optimizer tests where someone forgot to add subdomain tracking modifications.

If the RFC were an issue, then it seems like Google would have addressed this in the standard Google Analytics Tracking Code. As stands right now, if you don't do any subdomain tracking at all, then the cookies are set without the leading period. So this leads me to believe that it's a non-issue at least as far as cookie compliance is concerned.

Either way you approach this, you're going to have exceptions:

1. If you default to using the leading period, then anytime you add subdomain tracking on a site that already had Google Analytics implemented, then you'll have to consider how much of a negative impact using the leading period is going to have and possibly not use it.
2. If you default to not using the leading period, then anytime you add subdomain tracking you'll have to make sure/hope there aren't any sub-sub-domains.

For me, I find that the exceptions for #2 crop up far less frequently than for #1. Not only that, handling the exceptions for #2 is pretty cut and dry, whereas handling those for #1 involve much more of a judgment call.

Also, to be perfectly honest, I've always felt more comfortable not using the leading period. It's always felt like the right way to do it. It seems to lead to safer setups. But I can easily see how someone could have started out always using the leading period and so instead they feel more comfortable using, it feels right, it seems safer. So I'm OK with someone taking the #1 approach to it instead, but I'll probably continue taking the #2 approach.

February 10, 2011 12:49 PM

Steffen said:

Hey Jeremy, thanks for your post. Very interesting.

I'm facing the following problem: with a few days gap after deploying your recommended tracking setting, traffic from a referring subdomain drops significantly. Expected effect on _addIgnoredRef(). Meanwhile, direct traffic increases. That - in turn - is not what I expected and in my case not supposed to be. What's the benefit from tracking subdomain traffic as direct traffic? That's even more confusing than tracking as referring. I expected that traffic to become "internal" traffic. How to achieve that?
And why is that gap from ... say 10 days?

Thanks in advance.

February 24, 2011 7:56 AM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Steffen: I can't determine the exact cause without seeing the code or looking at the site, but if traffic from a subdomain is showing up as direct, then that indicates some type of code inconsistency between the main domain and the subdomain. Here are some things to consider:

1. Are you wanting to track the main domain and the subdomain together? Sometimes people want to track these separately, or they don't want to/can't track the subdomain for some reason and want it tracked as a referring source. This article assumes that you do want to track them together.

2. If you're tracking the main domain and the subdomain together, then the Google Analytics Tracking Code on each should be very similar, if not identical. In particular, the _setDomainName and _setAllowHash statements (or lack thereof) must be identical. You can't have a leading period on one and not on the other, use _setDomainName("none") on one and not on the other, or use _setAllowHash("false") on one and not on the other.

3. Are you running any Google Website Optimizer tests on either the main domain or the subdomain? Similar to #2, the Google Website Optimizer code must have the same set of modifications as your Google Analytics Tracking Code. This is fairly straightforward for the tracking script and conversion script, but the control script needs to be modified using equivalent urchin.js style modifications.

4. Is there any other Google Analytics Tracking Code on any of the pages? This includes legacy code, code put there by someone else for some other purpose, or even UTM code for Urchin. Any extra code like this will need to either be modified to match your Google Analytics Tracking Code or removed.

February 24, 2011 8:20 AM

Cory said:

Hi Jeremy,

This is such a great article. I recently spent a lot of time scratching my head over some self-referrals until we saw this.

I quickly implemented your code as outlined above on a simple (/path/page.aspx) www domain and a developer added matching script on a more complex transaction subdomain(pages.aspx?pid=000 etc)

Unfortunately, I'm able to see only traffic that moves from the "complex" (www) site to the "simple" (subdomain) site but not the other way around.

What do you think that means? On which CMS should I look to edit?

Thank you!

February 24, 2011 1:08 PM

Jeremy Aube, Director of Engineering Author Profile Page said:

@Cory: My previous comment most likely applies here as well. In particular, you should check both sites for legacy Google Analytics Tracking Code that might have a different set of modifications than the code you just added. The legacy code will then have to either be modified or removed.

February 24, 2011 1:20 PM

Peter O'Neill said:

Hi Jeremy,

Just had a long discussion with an ex-colleague about _addignoredref and want to clarify what the impact of it is.

In point 3 of the blog, you recommend using it to avoid self-referrals when a visit session expires between pageviews. That makes sense but I can't see this causing a high percentage of self-referrals. For most sites, this should occur a minimal number of times. If a site has many visits timing out (maybe due to video), would suggest increasing length of visit.

Instead won't using this code eliminate recording of all self referrals as they will all be reported as the previous referrers or as Direct? As you say in one of the comments, this information can be useful for finding untagged pages or untagged links between subdomains.

Thanks - Peter

March 4, 2011 6:25 AM<