
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?
- A visitor lands on a page
- 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.
- 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.
- 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:
- We created a Custom HTML tag that creates an initialTrafficSource cookie. If such cookie already exists, the script will do nothing.
- We created a 1st-party cookie variable that reads the initialTrafficSource cookie.
- 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.
- 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:
- First check in the Developer Tools of your browser
- Then check whether your 1st-party cookie variable properly reads its value (you can see that in the GTM Preview and Debug console)
- Then click the Tag Assistant extension’s icon once again and click Google Analytics
- 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. - 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).

64 COMMENTS
Sorry getting an error
Error at line 151, character 5: Parse error. ')' expected
Hey, sorry. The text editor stripped out part of the code. I've updated it now.
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.
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!
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.
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?
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.
Thanks Julius. That's great. I'll crack on with it now!
This is working very well :) Could a possible future enhancement be to include the landing page path/URL?
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.
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
Thanks for your contribution!
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!
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".
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.
Hi, Will it help to track the exact source url of the visitor?
If yes where exactly we can see the source url?
Thanks.
Does this still work? I'm not seeing the initialTrafficSource cookie appearing under the domain of any of my sites.
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?
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.
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 :)
Hi, unfortunately,this solution does not support cross-domain setups.
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 :)
Are you comparing Facebook conversions in GA vs Facebook conversions in Facebook's reports?
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!
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
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
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.
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!
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!
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
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.
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!
Hey, is there utm_campaign in the URL?
Ah, no. Does it only apply to URLs that already include UTM parameters?
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.
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!
Hi, did you get the way to get second and third traffic source?
Hi Julius!
Whats the difference between this "initial traffic source" and "First Interaction" in Attribution modeling
Thank you so much
No difference. Except that you can use Initial Traffic Source in any GA report, not only attribution.
But, its not the same as Create a segment with "Sequence start" > First user interaction
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
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.
Julius, can I add fbclid to this script by adding it to the keyMap and gaParams if statement, following the format of the gclid?
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 ?
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?
Source/medium shows the latest traffic source. Initial shows the first one that was captured with that cookie.
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.
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.
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.
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
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?
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
Hi, use this https://www.bounteous.com/insights/2018/05/09/reusing-google-analytics-campaign-information-google-tag-manager/
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.
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?
1. Yes
2. You would need to learn Javascript and code it yourself.
3. I don't have a ready-made solution for it.
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?
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!
Hi, no, it shouldn't if everything is configured correctly.
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
Same question as Todd Crump: Is it possible to make this work in GA4?
GA4 does this automatically
Is this solution will work with GA4 property?
You don't need this for GA4. It tracks this automatically with things like "First user medium" dimension