• Courses
    • Courses
    • Course bundles
  • Blog
  • Services
  • Resources
    • Youtube channel
    • E-books and Guides
    • GTM Recipes
    • View All Resources
    • GTM Community
    • GA4 community
  • About
    • About
    • Contact
  • Login
  • Courses
    • Courses
    • Course bundles
  • Blog
  • Services
  • Resources
    • Youtube channel
    • E-books and Guides
    • GTM Recipes
    • View All Resources
    • GTM Community
    • GA4 community
  • About
    • About
    • Contact
  • Login

October 17, 2018

[VIDEO] Track the Initial Traffic Source of the Visitor with Google Tag Manager

This week, the format of the content is a bit different. I did the 2nd guest video on Julian’s MeasureSchool channel (I’m pretty sure that no introduction is needed here and every one of you has watched at least several of his videos). This time, I’ve explained a technique that will be useful if you want to know not only the last traffic source/medium that drove the conversion but also the very first one that introduced your brand to that visitor.

If you are in a hurry, go ahead and watch the video. If you have more time, feel free to read the blog post as well.

 

Why do we need this solution?

Out of the box, Google Analytics offers Acquisition reports and one of the most popular features there are Source/Medium reports. They enable you to see which traffic sources (e.g. Google, Facebook, Email campaigns) are driving the most visitors and if you have configured goals/ecommerce tracking, you can also see which of those sources are actually converting the best.

Google Analytics uses last non-direct click attribution, therefore, the conversion will be attributed to the most recent non-direct traffic source. But what if you wanted to see what was the initial traffic source that initially drove the visitor to your website in the first place? Even though it’s possible to compare attribution models in GA, you’d like to have more data outside the Model Comparison Tool.

In this guide, I’ll show you how to track the initial traffic source that drove the visitor to your website, thus you will be able to use this data and compare your dimensions and metrics not only under the last non-direct click attribution but also as the first-click attribution.

Although the solution is far from being perfect and may be inaccurate in some cases, it may still give you some good insights after you gather more data for a longer period of time.

Interested? Let’s start!

The workflow

This time, I will be using a modified script that is based on the UTMZ Cookie Replicator (created by the team of Lunametrics). This replicator is an awesome solution that imitates the cookie used by the Classic Google Analytics. That cookie contained the traffic acquisition data of the current session, therefore, you could use its value as a tag-firing condition or pass that information to other tools.

However, this utmz cookie went missing after the Universal Analytics was introduced. Luckily, good people at Lunametrics shared their own solution that imitates the cookie and lets us use it in GTM.

The solution (explained in this blog post) is heavily based on the JavaScript that is used in the UTMZ replicator, however, there are some modifications made, so please use the script that I’ll share with you below.

So what’s the workflow?

  1. A visitor lands on a page
  2. A Custom HTML tag (with the modified Lunametrics’ JavaScript) fires and sets the initialTrafficSource cookie. That cookie contains the traffic acquisition data. If such cookie already existed in a browser, the script will not overwrite and leave as it is.
  3. Then, with the help of 1st-party cookie variable, GTM will read the cookie’s value and will pass the data over to Google Analytics as a user-scoped custom dimension.
  4. Test it. Done!

 

#1. Custom HTML tag

Let’s start with a tag. Here is the JavaScript that you need to fire on all pages (at least for now):

<script>
/**
* Original script is created by Lunametrics 
* https://www.lunametrics.com/labs/recipes/utmz-cookie-replicator-for-gtm/
* Modified by Analytics Mania https://www.analyticsmania.com/
*
* Data is stored in the __initialTrafficSource cookie in the following format; brackets
* indicate optional data and are aexcluded from the stored string:
*
* utmcsr=SOURCE|utmcmd=MEDIUM[|utmccn=CAMPAIGN][|utmcct=CONTENT]
* [|utmctr=TERM/KEYWORD]
*
* e.g.:
* utmcsr=example.com|utmcmd=affl-link|utmccn=foo|utmcct=bar|utmctr=biz
*/
(function(document) {

  var referrer = document.referrer;
  var gaReferral = {
    'utmcsr': '(direct)',
    'utmcmd': '(none)',
    'utmccn': '(not set)'
  };
  var thisHostname = document.location.hostname;
  var thisDomain = getDomain_(thisHostname);
  var referringDomain = getDomain_(document.referrer);
  var sessionCookie = getCookie_('__utmzzses');
  var cookieExpiration = new Date(+new Date() + 1000 * 60 * 60 * 24 * 30 * 24);
  var qs = document.location.search.replace('?', '');
  var hash = document.location.hash.replace('#', '');
  var gaParams = parseGoogleParams(qs + '#' + hash);
  var referringInfo = parseGaReferrer(referrer);
  var storedVals = getCookie_('__utmz') || getCookie_('__utmzz');
  var newCookieVals = [];
  var keyMap = {
    'utm_source': 'utmcsr',
    'utm_medium': 'utmcmd',
    'utm_campaign': 'utmccn',
    'utm_content': 'utmcct',
    'utm_term': 'utmctr',
    'gclid': 'utmgclid',
    'dclid': 'utmdclid'
  };

  var keyFilter = ['utmcsr', 'utmcmd', 'utmccn', 'utmcct', 'utmctr'];
  var keyName,
     values,
    _val,
    _key,
    raw,
    key,
    len,
    i;

  if (sessionCookie && referringDomain === thisDomain) {

    gaParams = null;
    referringInfo = null;

  }

  if (gaParams && (gaParams.utm_source || gaParams.gclid || gaParams.dclid)) {

    for (key in gaParams) {

      if (typeof gaParams[key] !== 'undefined') {

        keyName = keyMap[key];
        gaReferral[keyName] = gaParams[key];

      }

    }

   if (gaParams.gclid || gaParams.dclid) {

    gaReferral.utmcsr = 'google';
    gaReferral.utmcmd = gaReferral.utmgclid ? 'cpc' : 'cpm';

   }

  } else if (referringInfo) {

    gaReferral.utmcsr = referringInfo.source;
    gaReferral.utmcmd = referringInfo.medium;
    if (referringInfo.term) gaReferral.utmctr = referringInfo.term;

  } else if (storedVals) {

    values = {};
    raw = storedVals.split('|');
    len = raw.length;

    for (i = 0; i < len; i++) {

      _val = raw[i].split('=');
      _key = _val[0].split('.').pop();
      values[_key] = _val[1];

    }

    gaReferral = values;

  }

  for (key in gaReferral) {

    if (typeof gaReferral[key] !== 'undefined' && keyFilter.indexOf(key) >-1) {

      newCookieVals.push(key + '=' + gaReferral[key]);

    }

  }

  if (!getCookie_('initialTrafficSource')) {
    writeCookie_('initialTrafficSource', newCookieVals.join('|'), cookieExpiration, '/', thisDomain);
  }

  writeCookie_('__utmzzses', 1, null, '/', thisDomain);

  function parseGoogleParams(str) {

    var campaignParams = ['source', 'medium', 'campaign', 'term', 'content'];
    var regex = new RegExp('(utm_(' + campaignParams.join('|') + ')|(d|g)clid)=.*?([^&#]*|$)', 'gi');
    var gaParams = str.match(regex);
    var paramsObj,
      vals,
      len,
      i;

    if (gaParams) {

      paramsObj = {};
      len = gaParams.length;

      for (i = 0; i < len; i++) {

        vals = gaParams[i].split('=');

        if (vals) {

          paramsObj[vals[0]] = vals[1];

        }

       }

     }

     return paramsObj;

  }

  function parseGaReferrer(referrer) {

    if (!referrer) return;

    var searchEngines = {
      'daum.net': {
        'p': 'q',
        'n': 'daum'
      },
      'eniro.se': {
        'p': 'search_word',
        'n': 'eniro '
       },
      'naver.com': {
        'p': 'query',
        'n': 'naver '
      },
      'yahoo.com': {
        'p': 'p',
        'n': 'yahoo'
      },
      'msn.com': {
        'p': 'q',
        'n': 'msn'
      },
      'bing.com': {
        'p': 'q',
        'n': 'live'
      },
      'aol.com': {
        'p': 'q',
        'n': 'aol'
      },
      'lycos.com': {
        'p': 'q',
        'n': 'lycos'
      },
      'ask.com': {
        'p': 'q',
        'n': 'ask'
      },
      'altavista.com': {
        'p': 'q',
        'n': 'altavista'
      },
      'search.netscape.com': {
        'p': 'query',
        'n': 'netscape'
      },
      'cnn.com': {
        'p': 'query',
        'n': 'cnn'
      },
      'about.com': {
        'p': 'terms',
        'n': 'about'
      },
      'mamma.com': {
        'p': 'query',
        'n': 'mama'
      },
      'alltheweb.com': {
        'p': 'q',
        'n': 'alltheweb'
      },
      'voila.fr': {
        'p': 'rdata',
        'n': 'voila'
      },
      'search.virgilio.it': {
        'p': 'qs',
        'n': 'virgilio'
      },
      'baidu.com': {
        'p': 'wd',
        'n': 'baidu'
      },
      'alice.com': {
        'p': 'qs',
        'n': 'alice'
      },
      'yandex.com': {
        'p': 'text',
        'n': 'yandex'
      },
      'najdi.org.mk': {
        'p': 'q',
        'n': 'najdi'
      },
      'seznam.cz': {
        'p': 'q',
        'n': 'seznam'
      },
      'search.com': {
        'p': 'q',
        'n': 'search'
      },
      'wp.pl': {
        'p': 'szukaj ',
        'n': 'wirtulana polska'
      },
      'online.onetcenter.org': {
        'p': 'qt',
        'n': 'o*net'
      },
      'szukacz.pl': {
        'p': 'q',
        'n': 'szukacz'
      },
      'yam.com': {
        'p': 'k',
        'n': 'yam'
      },
      'pchome.com': {
        'p': 'q',
        'n': 'pchome'
      },
      'kvasir.no': {
        'p': 'q',
        'n': 'kvasir'
      },
      'sesam.no': {
        'p': 'q',
        'n': 'sesam'
      },
      'ozu.es': {
        'p': 'q',
        'n': 'ozu '
      },
      'terra.com': {
        'p': 'query',
        'n': 'terra'
      },
      'mynet.com': {
        'p': 'q',
        'n': 'mynet'
      },
     'ekolay.net': {
        'p': 'q',
        'n': 'ekolay'
     },
     'rambler.ru': {
       'p': 'words',
       'n': 'rambler'
     },
     'google': {
       'p': 'q',
       'n': 'google'
     }
   };
   var a = document.createElement('a');
   var values = {};
   var searchEngine,
     termRegex,
     term;

   a.href = referrer;

   // Shim for the billion google search engines
   if (a.hostname.indexOf('google') > -1) {

    referringDomain = 'google';

   }

  if (searchEngines[referringDomain]) {

    searchEngine = searchEngines[referringDomain];
    termRegex = new RegExp(searchEngine.p + '=.*?([^&#]*|$)', 'gi');
    term = a.search.match(termRegex);

    values.source = searchEngine.n;
    values.medium = 'organic';

    values.term = (term ? term[0].split('=')[1] : '') || '(not provided)';

  } else if (referringDomain !== thisDomain) {

    values.source = a.hostname;
    values.medium = 'referral';

  }

   return values;

  }

function writeCookie_(name, value, expiration, path, domain) {

    var str = name + '=' + value + ';';
    if (expiration) str += 'Expires=' + expiration.toGMTString() + ';';
    if (path) str += 'Path=' + path + ';';
    if (domain) str += 'Domain=' + domain + ';';

    document.cookie = str;

}

      function getCookie_(name) {

        var cookies = '; ' + document.cookie
        var cvals = cookies.split('; ' + name + '=');

        if (cvals.length > 1) return cvals.pop().split(';')[0];

      }

function getDomain_(url) {

  if (!url) return;

  var a = document.createElement('a');
  a.href = url;

  try {

    return a.hostname.match(/[^.]*\.[^.]{2,3}(?:\.[^.]{2,3})?$/)[0];

  } catch(squelch) {}

 }

})(document);
</script>

 

 

This JavaScript will read the data from:

  • document.referrer global JavaScript variable (read referrer)
  • UTM parameters
  • gclid and dclid query parameters
  • will try to match the referrer data against the know search engines

And if none of the above data exists, the traffic source will be set as (direct).

The format of the initialTrafficSource cookie formatted as follows: utmcsr=example.com|utmcmd=affl-link|utmccn=foo|utmcct=bar|utmctr=biz

  • utmcsr is campaign source
  • utmcmd is campaign medium
  • utmccn is campaign name
  • utmcct is campaign content
  • utmctr is campaign term

So after you have created the Custom HTML tag and set it to fire on all pages, save it.

Refresh the GTM Preview and Debug mode and head over to the website you’re currently working on. Refresh the page and the GTM debugging console will appear. Check whether your Custom HTML cookie-setting tag has fired. If yes, you need to check whether the cookie was properly created.

#1.1. Checking the cookie

There are several options how you can do that. One is to use the browser’s built-in developer tools. The other one is to use browser extensions, like EditThisChookie.

This time, I’ll use the default browser’s functionality. If you are on Chrome, click Three Dots icon in the top right corner, then choose More Tools > Developer Tools.

Go to Applications tab and under the Storage section choose Cookies. Click the domain that you’re currently on. This will open a list of all the 1st-party cookies that are stored in your browser by this domain. Start looking for the initialTrafficSource cookie. Next to its name, you’ll see the value.

Its value may be different from yours because it depends on how you landed on that page in the first place. But if its format looks similar to the screenshot above, then you’re on the right track.

By default, Google Tag Manager does not recognize cookies and does not turn them into variables, thus you won’t see that cookie in your Preview and Debug (P&D) mode’s Variables tab… unless you create a variable by yourself.

In GTM, go to Variables > New and create a 1st-party cookie variable with the following settings:

After you’re done, save the variable, refresh the P&D mode and then refresh the page that you’re currently working on. In P&D console, choose any event (in the left side) and then go to the Variables tab. Scroll down and keep looking for that 1st-party cookie variable. Here it is:

If the value of your cookie variable is undefined, please check the name of the cookie that you have entered in that variable. It is case-sensitive. It must be precisely initialTrafficSource, NOT initialtrafficSource, InitialTrafficSource, or anything else.

 

#2. Create a Custom Dimension

The next step is to pass this custom data over to Google Analytics. We’ll achieve this thanks to a feature called Custom Dimensions.

First, go to your Google Analytics account, choose the property that you wish to send the data to and click the gear icon in the bottom left corner. Then in the Property section go to Custom Definitions > Custom Dimensions.

Create a new Custom Dimension. You can name it whatever you want but I prefer Initial Traffic Source. Choose the User as a scope.

Click Save and take a closer look at the number that you’ll see in the little code snippets. In my case, it’s 1 but in your property the number may (and probably will) be totally different. Memorize this number.

Now, go back to your Google Tag Manager account. Let’s set that Custom Dimension. There are two options how you can do that and it depends on how you implemented other GA tag configurations. If you use Google Analytics Settings Variable, set the Custom Dimension there.

If you set the GA settings directly in every GA tag, you’ll need to set the following settings in the Pageview tag. The screenshot below will be based on the GA Settings Variable.

Open the variable and click More Settings > Custom Dimensions and enter the following:

  • In the Index field, enter the number of the custom dimension that you have just created.
  • In the Dimension Value field, insert the 1st-party cookie variable that you have created in the previous chapter. You can do that by clicking the button with a Lego brick and choosing the variable from the list.

Save the variable.

 

#3. Fire the Custom HTML tag before the Pageview tag

The next step is very important. You need to make sure that the Custom HTML tag (that sets the initialTrafficSource cookie) fires before the GA pageview tag. Otherwise, some of your visitors (that just land and then bounce) won’t get the Custom Dimension sent to Google Analytics (because of the cookie not being available in the moment of the Pageview event).

So the next GTM feature that we’ll make use of is Tag Sequencing. It allows you to fire a tag before another tag fires.

In your GTM account, go to Tags and open the GA Pageview tag. Click Advanced Settings > Tag Sequencing. Click the checkbox Fire a Tag before the GA Pageview fires and choose that Custom HTML tag that you created in step #1. Click Save.

Also, open the Custom HTML tag and remove the All Pages trigger leaving only the Tag Sequencing as the only way that fires that tag.

 

#4. Let’s test

Let’s do a quick recap of what we just did:

  1. We created a Custom HTML tag that creates an initialTrafficSource cookie. If such cookie already exists, the script will do nothing.
    1. We created a 1st-party cookie variable that reads the initialTrafficSource cookie.
  2. Created a Custom Dimension called Initial Traffic Source and set its scope to User. This means that all hits of the current and future sessions of that user will be set with the value of our initialTrafficSource cookie. If you’re new to scopes, read this guide on Google’s knowledge base. Also, we updated the Google Analytics Settings variable. From now on, it will be pushing the Initial Traffic Source as a custom dimension to Google Analytics.
  3. We set the Custom HTML tag to fire before the GA Pageview Tag does (thanks to the feature called Tag Sequencing).

Let’s test. For a proper testing you’ll need to do the following:

  • Delete the initialTrafficSource cookie from the browser (after you open browser’s developer tools, go to Application > Storage > Cookies and delete the initialTrafficSource cookie). You can delete it by hitting the DELETE key in your keyboard. If you’re using some other browser (not Chrome), you’ll need to find out how to do this on your own.
  • Use the Google Tag Assistant Chrome Extension. If you’re new to it, read this guide.

Before you refresh the page, click the Tag Assistant icon and enable diagnostics:

Now, refresh the page. The Custom HTML tag must fire before the GA Pageview tag. If it did, check whether the cookie was properly stored:

  1. First check in the Developer Tools of your browser
  2. Then check whether your 1st-party cookie variable properly reads its value (you can see that in the GTM Preview and Debug console)
  3. Then click the Tag Assistant extension’s icon once again and click Google Analytics
  4. Then click Pageview.

    Go to Custom Metrics and see if the value of your cookie is displayed there. It won’t look as pretty as in the GTM’s Preview and Debug console. That’s because the Tag Assistant displays the value with the “equals” sign encoded:

    But that’s totally fine. In GA reports this custom dimension will be displayed more properly.
  5. Wait for several hours for the data to appear in your GA reports. For you, it might take even longer. Don’t panic for at least the first 24 hours.

 

Where can I see this data?

That’s up to you and your imagination. Here’s an example. Go to Acquisition reports > All Traffic > Source/Medium and add the Initial Traffic Source as the secondary dimension. If you have set goals or ecommerce tracking in GA, you can see in a single table what was the first traffic source of that user and what was the last traffic source of that conversion.

In the screenshot below I don’t have the goals or ecommerce set up (because that is a dummy account) but you get the idea.

 

Caveats

Even though this solution looks awesome, there are some serious drawbacks that you need to keep in mind.

  • This solution is based on cookies. If a visitor clears the browser or lands on a page with a different device, he/she will get a new initialTrafficSource cookie that will not represent the accurate situation. However, that’s the fundamental problem with many web analytics tools (GA included). So look at the data with a grain of salt.
  • This script cannot access historical data of the user. So if you implement it now, your already acquired users/visitors will probably get incorrect values. So you need to give it some time and collect more data. As time goes by, the number of actual new users will increase, thus the impact of your current visitors/users will be mitigated (to an extent).

 

Track the initial traffic source of a visitor: final words

I have to admit, trying this tracking technique, recording a video and writing a blog post was really fun. Although it required more time that it usually does for me to create content, that’s totally worth it. Huge thanks to Julian from MeasureSchool for inviting to his channel once again. If you haven’t yet, go definitely check his Youtube channel. That’s one of the places of the interwebz where I learned GTM.

If you just skimmed the blog post and scrolled down straight to the end of this article, here’s a quick recap of what I’ve done:

  • Implemented the Custom HTML tag that reads the referral data, UTMs, gclid and dclid parameters in the link, matches the referral data to known search engines and then creates a cookie with that data. That cookie is set only once (unless it gets deleted at some point).
  • Then we instructed GTM to read that cookie and send its value as a custom dimension to Google Analytics.
  • In order to be sure that the cookie is created before the GA Pageview tag fires, we used GTM’s Tag Sequencing.

This solution is not bulletproof, therefore, please have in mind its caveats as well (read the chapter right before the conclusion of this blog post).

Julius Fedorovicius
In Google Analytics Tips Google Tag Manager Tips
64 COMMENTS
Raj
  • Oct 17 2018
  • Reply

Sorry getting an error

Error at line 151, character 5: Parse error. ')' expected

Julius Fedorovicius
  • Oct 17 2018
  • Reply

Hey, sorry. The text editor stripped out part of the code. I've updated it now.

Headwurdz
  • Oct 17 2018
  • Reply

Thanks for the post, one rec... for folx with slow brains like me, prior to "#4. Let’s test", you should remind readers to publish the tag. I didn't publish and went to the Chrome assistant and didn't see the "custom metric" field, until I published. If I just overlooked where you told us to publish, by bad... I told you my brain was slow.

Dan
  • Oct 17 2018
  • Reply

Hi,
I've been looking for something along these lines, but I'm wondering, how is this custom dimension different from GA's built-in multi-step funnel dimensions?
Thanks, great post!

    Julius Fedorovicius
    • Oct 26 2018
    • Reply

    Because you can use this dimension (Initial Traffic Source) outside of Multi-channel reports. If you think that I misunderstood your question, please let me know.

Josh
  • Oct 19 2018
  • Reply

Initial traffic source for conversion is the vital metric for my project, so this is extremely helpful – thank you. For various reasons, I'm using gtag.js rather than GTM. Do you know if this method can be achieved by altering the gtag.js snippet to send the cookie value as a custom dimension?

Julius Fedorovicius
  • Oct 19 2018
  • Reply

As for the custom script, it does not matter whether you're using GTM + GA, or plain gtag.js. In case of gtag.js, you need to ask a developer to read the initialTrafficSource cookie and by following these instructions (https://developers.google.com/analytics/devguides/collection/gtagjs/custom-dims-mets) to send the custom dimension to GA.

Josh
  • Oct 19 2018
  • Reply

Thanks Julius. That's great. I'll crack on with it now!

Josh
  • Oct 19 2018
  • Reply

This is working very well :) Could a possible future enhancement be to include the landing page path/URL?

    Julius Fedorovicius
    • Oct 20 2018
    • Reply

    Yeah, I guess it could be. But you can already to the same solution by yourself. When a visitor lands on any page, create a cookie. In that cookie, you can store a variable {{Page URL}}.

    Do not fire the Custom HTML tag that sets the cookie if the cookie already exists in the browser.

Josh
  • Oct 20 2018
  • Reply

I've adapted the script to include a 'utmcurl': window.location.href. Thanks again for this tutorial – it's going to have a great impact on my marketing efforts. Josh

    Julius Fedorovicius
    • Oct 21 2018
    • Reply

    Thanks for your contribution!

    Alberto
    • Jun 12 2020
    • Reply

    Hi Josh,

    I am interested in doing exactly that, would you mind sharing exactly how you did it? My Javascript knowledge is limited.

    Thank you in advance!

Abhishek
  • Dec 19 2018
  • Reply

Hello Julius,

I did step-by step as its mentioned here. Though now it has been 3-days but still no results showing in google analytics when I select this custom dimension.

So, when I tracked the Cookie: information through page (developer tools) it shows correct information.

But when I checked through tag assistant by clicking on "page view requests" i did not find "custom metrics".

    Julius Fedorovicius
    • Dec 20 2018
    • Reply

    If you don't see custom dimensions in the Tag Assistant, you're not passing them.
    1. Have you created Custom Dimensions in GA?
    2. Have you configured your GA Settings Variable to pass the custom dimensions to GA?
    3. Have you created the cookie variable and does it return the actual cookie value? (not "undefined"? Carefully rewatch the video and follow all the steps once again. Because you're missing something in the process.

Swati
  • Jan 17 2019
  • Reply

Hi, Will it help to track the exact source url of the visitor?

If yes where exactly we can see the source url?

Thanks.

Phil
  • Jan 24 2019
  • Reply

Does this still work? I'm not seeing the initialTrafficSource cookie appearing under the domain of any of my sites.

Lars
  • Jan 28 2019
  • Reply

Hey there it still works but fr campaign I see utmccn=(not set) (rest of the parameter is okay and google also sees the campaign parameter in the user explorer)

Anybody else having this problem? Something with the script maybe?

    Julius Fedorovicius
    • Jan 28 2019
    • Reply

    utmccn will work only if the utm_campaign is available in the URL. If you want to access the campaign name when the user comes from Google Ads, it will not display because it is impossible to access that information via frontend.

Marcio Santos
  • Feb 14 2019
  • Reply

Thank you Julius!!

I'm seeing a lot of self referrals in my "Initial Traffic Source" Dimension in GA.

My setup:

>siteA.com sends users to siteB.com where purchases are completed.
>your cookie only fires on siteA.com
>crossdomain tracking enabled in GTM
>referral exclusion added in GA include both siteA.com and siteB.com
>Initial Traffic Source = utmcsr=siteA.com|utmcmd=referral|utmccn=(not set)

I hope you can shed some light on this for me :)

    Julius Fedorovicius
    • Feb 14 2019
    • Reply

    Hi, unfortunately,this solution does not support cross-domain setups.

      Marcio Santos
      • Feb 14 2019
      • Reply

      Ahh okay.
      Thanks for your reply.

      I implemented this solution to help me better track the conversions on my paid facebook ads. I already use utm parameters, cross domain tracking, and I push conversion values through the dataLayer, but I still only see a fraction of my conversions in GA versus the conversions I see in Facebook (and other platforms). I know I may seem like I'm asking for a lot, but I would be super interested to know how you usually solve this :)

        Julius Fedorovicius
        • Feb 15 2019
        • Reply

        Are you comparing Facebook conversions in GA vs Facebook conversions in Facebook's reports?

Jose
  • Feb 26 2019
  • Reply

Hi! How its going. I have a weird case. I have a domain.com and a sub.domain.com. I installed the initialtrafficsource with sub.domain.com analytics ID

But in when i go to domain.com i can see the cookie as well.

I have installed UTMZ cookie in domain.com and this one doent appear as cookie in sub.domain.com

Why the initaltrafficsourcecookie is present in domain.com and sub.domain.com?

THX!

    Julius Fedorovicius
    • Feb 27 2019
    • Reply

    Hey, that's because the cookie is set on the top-level domain (domain.com), it is accessible on all subdomains that belong to the domain.com

Jose
  • Mar 1 2019
  • Reply

I implemented initialtrafficsource only in sub.domain.com. So its normal if my gtm container is XXX for my domain.com and my gtm container is YYY for my sub.domain.com i had the initialtrafficsource in both?

Why its not happening the same with UTMZ if i implemented in domain.com? Why the cookie its not in sub.domain.com as well?

Thx for ur patience

    Julius Fedorovicius
    • Mar 2 2019
    • Reply

    Because you can set the scope of the cookie - either it will be accessible only on a particular subdomain or across all subdomains. I don't remember the precise settings of the UTMZ replicator but the initial traffic source cookie definitely spans across all subdomains of a single domain.

Mark McLaren
  • Mar 7 2019
  • Reply

Hi Julius! I have another question for you about the cHTML script. The custom dimension values I see in GA don't include 'utmcct'. Is this picked up by the script? I'm interested in adding a variable that would grab the URL of the page the user landed on in their first visit to the site. Maybe inserting window.location.href into the script somewhere so it is assigned to utmcct? Thanks for any advice!

Dux
  • Mar 15 2019
  • Reply

Hi Julius, great stuff here! I have just a small issue - encoding. We currently use a UTM format with "something | something | something" for all UTMs. Eg. Our campaigns are "Stage | platform | region | country".

What I see in the cookie is cut off before the |. I get a "Stage ", so I concluded that | is bugging with the tag logic, as | is used as a divider.

Is there a way to change the encoding or use a different sign other than | to divide utmcsr, utmcmd etc?

Love your posts!

Edyta
  • Apr 5 2019
  • Reply

Hi
I need a help with tracking content engagement.

I want to know "average # of visits before a blog reader turns into a customer" and "how many weeks does it take for a blog reader to become a customer".

do you know how to track it in google analytics using GTM

Ruben Härtel
  • Apr 19 2019
  • Reply

Thank you for this tutorial. I have used it but got an error after a page refresh. After trying and searching for a while I found the causing error which is a used white space in the cookie value. It seems to be not allowed and can cause in some cases an internal server error.

Therefore I removed the with space in line 22 of the cHTML-Script within the array value of ‘utmccn’. I simply changed “(not set)” to (notset). That change made it work.

Hayley Crandell
  • Apr 26 2019
  • Reply

Hi Julius - I'm only seeing the utmccn= value, which is (not set) regardless of the actual source. I'm copying the script exactly, so not sure of the likely issue here. Do you have any ideas please?
Thanks!

    Julius Fedorovicius
    • Apr 26 2019
    • Reply

    Hey, is there utm_campaign in the URL?

      Hayley Crandell
      • Apr 26 2019
      • Reply

      Ah, no. Does it only apply to URLs that already include UTM parameters?

        Julius Fedorovicius
        • Apr 26 2019
        • Reply

        Yes. If you were expecting get the Google Ads campaign name, that's impossible to get by any a script running on your page, including this one.

Camille
  • Apr 30 2019
  • Reply

Hi guys,

I tried many times to get accurate source data that I could export to other tools as a variable, this is now possible thanks to your brilliant post. Thank you so much for taking the time to share this!

I am now going to try an edit the script to also get 2nd and 3rd traffic source as it is relevant for one of my clients. This has opened a whole new world!

    Ken
    • Sep 18 2020
    • Reply

    Hi, did you get the way to get second and third traffic source?

Jose
  • May 6 2019
  • Reply

Hi Julius!
Whats the difference between this "initial traffic source" and "First Interaction" in Attribution modeling

Thank you so much

    Julius Fedorovicius
    • Jun 10 2019
    • Reply

    No difference. Except that you can use Initial Traffic Source in any GA report, not only attribution.

      Jose
      • Jul 14 2019
      • Reply

      But, its not the same as Create a segment with "Sequence start" > First user interaction

Dhana Suryaa
  • Jun 7 2019
  • Reply

Hi Julius, I followed your implementation process & previewed it. Only the "utmccn=(not set)" value is captured in cookies whereas in your video all other sources like sources, medium & content, etc are all captured.

I have followed all your step properly & tested it.

Is there, any issue with the updated cHTML?

For reference, see the image: https://imgur.com/xxA6LCO

    Julius Fedorovicius
    • Jun 10 2019
    • Reply

    Hey, delete that cookie and try testing from scratch. I'd say that this is some legacy of your initial tests.

    I've just tried the listener on my own and it works fine.

Bobby Brooks
  • Jul 2 2019
  • Reply

Julius, can I add fbclid to this script by adding it to the keyMap and gaParams if statement, following the format of the gclid?

Bastien
  • Jul 3 2019
  • Reply

Hi,

Thank you for the code.

I maybe don't understand something. I see the code for gclid or dclid but I don't see the same for msclid ou facebook click id.

Do we have to add other specific url parameter to the script ?

Andrew
  • Aug 27 2019
  • Reply

I'm still not 100% clear why this is needed if GA already tells us the Source/Medium for the conversion. If you go to Acquisition > All Traffic > Source/Medium > Set the goal you want to view in the Conversions column, this will tell you the initial source won't it? Guess I'm not sure what the difference is between Source/Medium and initial source. Can anyone explain?

    Julius Fedorovicius
    • Aug 27 2019
    • Reply

    Source/medium shows the latest traffic source. Initial shows the first one that was captured with that cookie.

      Andrew
      • Sep 17 2019
      • Reply

      Thank you Julius for the explanation. By Google's definition, Source/Medium seems a bit misleading, because to me it means the initial source the traffic came from, but that's not what you're saying. So, if I look at the Source/Medium for the goals I have set up in Google Analytics, what I am seeing is the last known source before the goal/conversion took place correct? So, if a person clicked on a Bing Ad, then Google Ad, then my Facebook ad and converted, the Source/Medium would be Facebook? I guess this is last click attribution? Thanks again.

        Julius Fedorovicius
        • Sep 19 2019
        • Reply

        My "initial traffic source" and Google's source/medium are two different things. GA reports the last non-direct traffic source. If I land on a page from google search (and don't convert) that session would still be attributed to the organic medium.

        My solution tracks the first known source. Google - last (non-direct). But mine always should be taken with a grain of salt because it is based on cookies, meaning that maybe visitor's ACTUAL initial source was different but at that moment a different device was used.

Andrew
  • Sep 19 2019
  • Reply

Thanks Julius for explaining. Much appreciated. This all makes sense now. I have product profile page on a software review site (e.g. Capterra) and I was trying to figure out how many conversions came from there. Since software review sites tend to fall somewhere in the middle to bottom of the sales funnel and aren't typically the last click before a conversion, it makes sense now that I don't see many conversions coming from this source. I think folks look at software review sites somewhere in the middle of the customer journey. Now if a click on our profile from this site resulted in a conversion immediately afterwards, then I'd expect to see it listed as the source/medium in GA, but I suspect visitors are clicking on the profile and then clicking on my Google ad AND THEN converting. Anyway, I appreciate your work. Unfortunately, I had to remove the script from GTM. GA was throwing an "Invalid AdWords gclid" error and reporting that the gclid parameter on the landing page URL for my ads was being dropped (I use auto-tagging in Google Ads). Once I removed the initial source script from GTM, the error message was resolved.

Martin
  • Oct 28 2019
  • Reply

Hi Julius.
Thanks for the great post. Just implemented the solution and looking forward to the results.
What can I do to expand the solution? I would like to have the same campaign information, but based on the CURRENT session of the user in order to fire certain sales tags relating to their source.
Kind Regards

Motasem
  • Feb 13 2020
  • Reply

I did it!
thanks a lot, but!

I have question, let say you are doing paid ads and you added traffic source parameter to the url in ads, how could traffic which coming from that ads not 100% registered in google analytics with the right traffic source?
if there is a chance to not have 100% accurate source data, how our this solution will solve the problem here?

Tim
  • Apr 28 2020
  • Reply

Great article Julius.

Wondering if you know of any recipes that set the traffic source for each session? For example, I'd like to fire a trigger for users who visited via organic search

    Julius
    • Apr 28 2020
    • Reply

    Hi, use this https://www.bounteous.com/insights/2018/05/09/reusing-google-analytics-campaign-information-google-tag-manager/

Mojo Creator
  • May 26 2020
  • Reply

Julius - thank you for your contribution to the community. Always great insight.

I have a question about leveraging the 'result' of the initial traffic source to trigger the corresponding conversion script. I would like to use one thank you page for multiple landing pages which receive clicks from multiple ad sources (Facebook Ads, Google Ads, Bing Ads, etc.).

What is your recommendation for configuring GTM so the right conversion script is fired based on the related initial traffic source?

For example, Facebook Ad Initial Traffic Source (m.facebook.com) is tracked from the Thank you page which then fires off the related Facebook Pixel.

Jaime
  • Jun 6 2020
  • Reply

This is awesome, is there a way to track multiple refer sources if a visitor uses different traffic sources? For example, initially they came from Facebook, the second time from YouTube, and finally they converted on a Google search?

    Julius
    • Jun 6 2020
    • Reply

    1. Yes
    2. You would need to learn Javascript and code it yourself.
    3. I don't have a ready-made solution for it.

Xtreme Hit
  • Sep 9 2020
  • Reply

I've confused by a few lines of code here that have to do with storedVals variable. It is set to equal getCookie_('__utmz') || getCookie_('__utmzz') - however, I do not see a cookie that is ever created called that. I don't see writeCookie_ function called with that argument. So else if (storedVals) would never execute as far as I can tell. If storedVals is set to getCookie_('initialTrafficSource') then that line of code will execute - else if (storedVals). Is this correct or am I missing something?

Chloe
  • Sep 30 2020
  • Reply

Hello, I find your tips on how to effectively use GTM great! However, I would like to ask if this can overwrite the process here: https://www.analyticsmania.com/post/transfer-utm-parameters-google-tag-manager/

Thank you and hoping for your reply!

    Julius Fedorovicius
    • Sep 30 2020
    • Reply

    Hi, no, it shouldn't if everything is configured correctly.

Todd Crump
  • Jan 25 2021
  • Reply

I deployed this using Google Tag Manager, and it works fine in UA, but in GA4, it caused all of my organic traffic to be counted as direct traffic. Any clue as to why this happened?

Thanks,

Todd

Keesjan
  • May 30 2022
  • Reply

Same question as Todd Crump: Is it possible to make this work in GA4?

    Julius Fedorovicius
    • Jun 3 2022
    • Reply

    GA4 does this automatically

Arthur
  • Jun 10 2022
  • Reply

Is this solution will work with GA4 property?

    Julius Fedorovicius
    • Jun 16 2022
    • Reply

    You don't need this for GA4. It tracks this automatically with things like "First user medium" dimension

Leave a comment Cancel reply

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

 

Hi, I'm Julius Fedorovicius and I'm here to help you learn Google Tag Manager and Google Analytics. Join thousands of other digital marketers and digital analysts in this exciting journey. Read more
Analytics Mania
  • Google Tag Manager Courses
  • Google Tag Manager Recipes
  • Google Tag Manager Resources
  • Google Tag Manager Community
  • Login to courses
Follow Analytics Mania
  • Subscribe to newsletter
Recent Posts
  • Google Analytics Client ID: What You Need to Know
  • Duplicate Events in Google Analytics 4 and How to Fix them
  • Track Videos with Google Analytics 4 and Google Tag Manager
Analytics Mania - Google Tag Manager and Google Analytics Blog | Privacy Policy
Manage Cookie Settings