Last Updated: 20 Oct 2023
_setVar() and the zero bounce rate bug in Google Analytics
UPDATE - Jan 27, 2009: Google has reportedly fixed the bug in GA that was causing the problem described on this page. Thus the fix is no longer necessary, but I will leave it here for historical reference.
Google Analytics has a _setVar()
function that lets you assign a single user-defined variable to be passed to your reports, which you can then see (and filter on).
Unfortunately, using _setVar()
on each page seems to break the bounce rate calculation in GA. This is because _setVar()
apparently records a second pageview when it is called, meaning a visitor who left after their first pageview didn't actually 'leave' in the eyes of GA because they had a second page view secretly recorded via _setVar()
. Thus the bounce rate in Google Analytics drops to zero (or near zero) because every single visitor is getting hit with two pageviews.
Conveniently, the value that you assign to _setVar()
is stored by GA in the _utmv
cookie, and the tracking code actually reads this cookie and passes back the value to Google Analytics, which records it for every single pageview, regardless of whether you set it with _setVar()
on that particular pageview. Therefore you don't need to call _setVar()
unless you actually want to change the user defined value. In fact, you shouldn't call it any more often than you have to, because you don't want to be creating these extra pageviews.
This lends itself to a nice solution to the problem: we'll simply check if the value we want to call _setVar()
with is already in the _utmv
cookie. If it is, we'll skip calling _setVar()
.
/* * getCookie(): given a cookie name, get its value. Returns null if the cookie can't be found. * From http://www.webreference.com/js/column8/functions.html * */ function getCookie(name) { var dc = document.cookie; var prefix = name + "="; var begin = dc.indexOf("; " + prefix); if (begin == -1) { begin = dc.indexOf(prefix); if (begin != 0) return null; } else begin += 2; var end = document.cookie.indexOf(";", begin); if (end == -1) end = dc.length; return unescape(dc.substring(begin + prefix.length, end)); } /* * utmvCookieCheck(): given a value, read the __utmv cookie and see if * that value is already set. Return true if so, false otherwise. * */ function utmvCookieCheck(value) { var utmvCookie = getCookie("__utmv"); if (utmvCookie == null) return false; // get rid of the Google's domain prefix ID, which appear on all // GA cookies utmvCookie = utmvCookie.replace(/^\d*\./, ''); return (utmvCookie == value) ? true : false; }
Now, just wrap your call to _setVar()
with a call to check if the cookie exists first:
<script type="text/javascript"> var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www."); document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E")); </script> <script type="text/javascript"> var pageTracker = _gat._getTracker("UA-XXXXXX-X"); var userDefinedValue = 'CHANGE_ME_TO_YOUR_DESIRED_VALUE_FOR_SETVAR'; if(!utmvCookieCheck(userDefinedValue)) { pageTracker._setVar(userDefinedValue); } pageTracker._trackPageview(); </script>
That's it. Now _setVar()
will only be called if the value isn't already set.
Discussion
Thanks for this it helped me
I think this won't solve the problem if you want to tag your visitors as soon as they arrive - say you're registering a visit from another site you're associated with, you'll never find out whether those visits bounce because you'll be recording the setVar() pageview on their landing page every time.
i reckon (hope) google will fix it the next time they update their graphs.
If the _setVar call a page view once it is called, and the _trackPageview also calls a page view, then even if we are checking whether or not the value has been previously set, we still don't bypass the problem of the initial bounce rate being off. For example:
User A arrives at landing page 1 with code X
- Script checks to see if “code” value has been set
- Script finds it hasn't been set, so it calls _setVar('code')
- _setVar make a page view request
- _trackPageview makes a page view request
- User A exits without going to any other page
In the scenario above, because _setVar was still called, it won't count as a bounce. Does my logic seem correct?
I'm wondering, is it possible to modify the cookie directly (instead of using _setVar) and insert the value you'd like to track? It seems to me once it's in the cookie, we're good to go, and the problem is called _setVar at any time.
Your thoughts are greatly appreciated.
@Tony
As far as I can tell you are right, but only in the situation that the first time someone visits that page and then leaves right away. But because it's stored in a cookie if they were to come back to the site later, the value would already be in the cookie and this time if they left it would be counted as a bounce.
But I may be thinking of it wrong
Thanks for the reply. I found that if we write to the cookie directly, we can avoid the double page track and the use of the _setVar.
var user_defined_value = encodeURI('SOMEVALUE'); Cleans up the user defined value document.cookie=“__utmv=##########.” + user_defined_value; Bypasses _setVar to set the user defined value cookie directly
——————————-
NOTE: ########## represents a unique id that's assigned to the account being tracked. This isn't the analytics id, but I believe corresponds to each profile. You'll have to open the cookies to figure out what it is for the profile you want to track.
Have you seen Google's fix actually working? We barely started using _setVar in 3/17/09 and we saw the bounce rate significantly drop.
As of January 2, 2009, I started having the problem of all of visitors counting as NON-BOUNCE visits because they suddenly all have at least two pages. I know this cannot be true as many of the visitors are on my site less than 10 seconds (and Google counts many as zero seconds on the site). If the above reason is not causing it (because Google fixed it at the beginning of the year), then what else might it be? I just cannot figure it out what started to make this happen.
Rich Woolf
BrownBible.com