The ROI Revolution Blog

January 5, 2011

If 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:

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.

Editor’s Note: If you’re interested in more actionable education on Google Analytics, check out our recent report on essential reports for ecommerce retailers!

Take the next step. Ecommerce retailers spending at least $5,000/month in AdWords qualify for a free 20-minute AdWords Diagnostic Checkup.

Comments

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!

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.

@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.

@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.

@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.

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?

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.

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

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?

@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.

@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.

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.

@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.

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.

@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.

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:

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?

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.

@Rob: You only need to implement cross-domain tracking if a visitor can move across root level domains. Going from avocacy.caenyc.org to http://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 http://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.

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:

@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.

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.

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.

@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.

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?

@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.

@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.

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.

@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.

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?

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.

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

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.

@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.

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.

@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:

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

@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).

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?)

@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.

@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.

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?

@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.

#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.

@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.

@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).

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?

@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.

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!

@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.

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)?

@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:

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.

@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.

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??

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.

Created a duplicate of the Master Profile in GA( for http://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 http://www.blog.example.com came to http://www.example.com. Both the sites don’t have default pages in the url( i.e no http://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?

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 http://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.

If I put the above line in the GA code, both for root domain and subdomain, would I still see the traffic coming from http://www.blog.example.com to http://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”?

@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.

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.

@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.

@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.

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.

Would this work for issues regarding a secure subdomain? The site is http://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.

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.).

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”.

@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.

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?

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.

@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.

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:

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.

@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.

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.

@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.

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.

@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.

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.

@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]);).

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:

@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.

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…

@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.

@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.

@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.

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.

@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.

@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.

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

@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$”.

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:

@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%.

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?

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

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.

@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.

@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.

I’m trying to understand this (eek) and set up my GA. I have a .com site such as: http://www.bookstore.com and on that same domain have added http://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.

@Jeremy, okay my website is a eg. http://www.bookstore.com and my blog is http://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; http://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!

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.

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.

@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:

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.

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.

@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.

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

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.”

I want to track http://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 http://www.example.com and not for static.example.com or any other subdomain?

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.http://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.

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.

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.

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.