Direct visits in Google Analytics

One of the most crucial points when assessing the structure of traffic sources, is the share of direct visits. Direct visitors are usually the most loyal to your site and therefore represents the most valuable traffic. Direct traffic is often classified as free, however in reality, it is a reward for your well-executed previous actions.

In Google analytics, direct traffic can be distinguished by dimension “source / medium” equal to “(direct) / (none)”. However, in overview reports, when adding “landing page” as a second dimension, you immediately start wondering why direct visits are landing on pages with really long URLs such as To understand this, it is important to remember that “(direct) / (none)” identifier is associated to all visits with empty HTTP referrer, which may be result of following:

  • User entered the site URL directly in browser address bar.
  • User visited the site by a browser-maintained bookmark.
  • User visited the site as first page in the window/tab.
  • User has installed security software (antivirus, firewall, etc.) which removes the referrer from all requests.
  • User is behind a proxy which removes the referrer from all requests.
  • User blocked passing referrer detail in a browser.

Is is clear that not all the visits identified as “(direct) / (none)” can be marked as direct traffic . Moreover is very likely that the share of such visits due the trend of using various anonymization tools will increase. Unfortunately there is no definitive solution to this issue, since the HTTP referrer is the only way how to determine where the visit originated. However, there is still one imperfect solution, based on assumption that vast majority of direct visits are landing on your homepage “/”, you can use simple javascript to set “source / medium” dimension to “(direct) / (none)” only when referrer is empty and user is landing on your homepage. Visits not meeting this condition are identified as “(unknown) / (none)”

if(!document.referrer) {
    if (window.location.pathname != '/')  {
        ga('set', 'campaignSource', '(unknown)');
        ga('set', 'campaignMedium', '(none)');

        _gaq.push(['_setCampSourceKey', '(unknown)']);
        _gaq.push(['_setCampMediumKey', '(none)']);