Solution to using UTM parameters & cookies to capture lead source information

Anonymous
Not applicable

*** NOTE: As Sanford pointed out in his post below, my code below has flaws and should be improved upon.I offer this only as an explanation of what worked for my purposes at the time. My team ended up not needing to capture this info, so I never went back and updated my code. Use it at your own risk. ***

I scoured these forums as well as myriad other sites and pages for weeks to figure out how to capture the original referral source of a user’s first visit, even if they don't convert at that time. But I never found a complete solution I could implement since I am not an experienced developer.  Therefore, in order to save others from the frustration I experienced, I offer the following detailed explanation of what finally worked for me. Specifically, this is how I was able to set the values from a URL with UTM parameters as cookies so a visitor’s original referral source could be captured.

For example, a new user comes to a demo signup form on a Marketo landing page from a LinkedIn ad containing UTM parameters. He leaves the page without filling out the form and visits our company’s main website.  He then later returns and completes a whitepaper request form. We want to know that he originally came from the LinkedIn ad.

Alternately, if you are sending users to your main website and want to pass UTM values to a Marketo form once they land on a Marketo landing page, uncomment the following line in the code.  (Don't forget to change "example.com" to your domain.)

document.cookie = key + "=" + query[key] + ";domain=.example.com;path=/";

Put the code below on your form pages.  (I know there are more efficient ways of writing it, but I don't have the Javascript skills to do so.)  You must have hidden fields on the forms to capture the UTM parameters.  When setting up the hidden fields on the form be sure to set Get Value from in the Autofill settings as “Cookie Value”.

In this example I have “utm_source”, “utm_campaign”, “utm_medium”, “utm_term”, and “utm_content” as hidden fields on my form.

Put the following in the <head> of your page:

<script type="text/javascript">

//This grabs the UTM parameters from the URL

function getQueryParams(qs) {

    qs = qs.split("+").join(" ");

    var params = {}, tokens,

    re = /[?&]?([^=]+)=([^&]*)/g;

    while (tokens = re.exec(qs)) {

params[decodeURIComponent(tokens[1])] = decodeURIComponent(tokens[2]);

    }

    return params;

}

//This sets the cookies

var query = getQueryParams(document.location.search);

for (var key in query) {

//console.log(key, query[key]);

  document.cookie = key + "=" + query[key];

//Setting domain and path attributes allow cookies to be read across subdomains

//To have a cookie available to all subdomains, you must put a . in front of your domain.

//Setting the path=/ will have the cookie be available within the entire specified domain.

//Don't forget to change "example.com" to your domain.

//document.cookie = key + "=" + query[key] + ";domain=.example.com;path=/";

}

//This gets the cookies

//ID = MARKETO FIELD NAME

var elem = document.getElementById("utm_source");

var elem2 = document.getElementById("utm_campaign");

var elem3 = document.getElementById("utm_medium");

var elem4 = document.getElementById("utm_term");

var elem5 = document.getElementById("utm_content");

elem.value = query.utm_source;

elem2.value = query.utm_campaign;

elem3.value = query.utm_medium;

elem4.value = query.utm_term;

elem5.value = query.utm_content;

//This runs the script when the page loads so the hidden fields are automatically populated

window.onload = getQueryParams;

</script>

17 REPLIES 17
Yanir_Calisar2
Level 3

See this Javascript that captures both first touch and last touch UTM params:

UTM-Tracking

https://github.com/yanirclsr/MarTech/tree/master/UTM-Tracking

Gunpreet_Kaur1
Level 3

Hi Yanir, Thanks for the js. We implemented the code on a page to test it out, ft fields are populating correctly on form submission but not lt(last touch). Is it suppose to pick the last touch just before the second-time form submission?

Also, what is the difference between utm-capture.js and utm-capture-hs.js ?

Web_Master1
Level 1

I took a stab at implementing the feedback from Sanford Whiteman and figured I'd share it even though I didn't end up using it. Note: I haven't actually tested the code below, so there are likely some issues. I'm just posting because it might be a better start than what's provided above.

Solution to using UTM parameters & cookies to capture lead source information. See https://nation.ma...

SanfordWhiteman
Level 10 - Community Moderator

Hi Rob!  Nice work there, but some red flags too...

You shouldn't use a timer/interval to integrate with Marketo forms, as they have their own robust event model, and similarly you don't need to manage your own hidden input elements... document.hasOwnProperty('cookie') doesn't really tell you anything about cookie support, and the domains setting doesn't seem to be used... and params[] = <value> is bad JS syntax (are you trying to append to the hash PHP-style?).

At any rate, I advise anyone interested in this area to check out ConversionPath (http://conversionpath.io/​).  I wrote the JS client piece, and it has seamless integration into the Marketo forms event model (as well as an integration into 3rd-party forms that I think is unprecedented) , a bunch of configurable bells and whistles, and is under continuous development.

Anonymous
Not applicable

I really wish the Munchkin code just took care of this for us, rather than each user having to Macguyver a solution. Frustrating!

Does anyone have a clear solution for this yet? Just looking to point our developer in the right direction.

Justin_Norris1
Level 10 - Champion Alumni

Jill Purse

If you want something that is more out-of-box, try Bizible: Bizible | B2B Marketing Attribution & Analytics Software

It "just works" out of the box, but is also very customizable/flexible for more unique requirements.

Anonymous
Not applicable

Hi Evan Vega

I used your code (with a small adjustment of checking whether a cookie is already set) using this code:

if (getCookie("utm_source").length < 1 || getCookie("utm_term").length < 1 || getCookie("utm_content").length < 1 || getCookie("utm_campaign").length < 1 || getCookie("utm_medium").length < 1) {

In this way the first set cookies don't get overwritten.

However I'm experiencing the problem of TypeError: elem is null. Do you have any idea how to deal with this?

Anonymous
Not applicable

Any chance you guys could post the final code you came up with? I am not an experienced coder and am struggling with this.

Anonymous
Not applicable

Beth -

I am currently using the code shown in my original post.  However, as Sanford pointed out, it has its flaws, so use at your own risk. 

Harish_Gupta6
Level 8

I am not sure how much is this helpful but did you try <input type="hidden" name="_mkt_trk" value=""/>.

_mkt_trk – this field carries the cookie information, so you’ll be able to track the individual’s web page visits. If you have Munchkin on your form page, Munchkin will automatically enter a value in this hidden form field. If not, read it from the cookie with the same name and pass it to Marketo in this field.

This will work until someone not clear the browser cookies.

Harish Gupta
SanfordWhiteman
Level 10 - Community Moderator

Harish, this is not accurate. Forms 2.0 itself will transfer the value of the cookie _mkto_trk (if it exists) to the field _mkt_trk on the Form object (not the Form's HTML element, the Form's JS object).  Munchkin does not need to be running on the form page, nor do you need to manually transfer the cookie into a hidden form input.

Justin_Norris1
Level 10 - Champion Alumni

There is also this official solution offered by Marketo support in this community as well, so you know it is supported.

Get URL Parameters via JavaScript on a Marketo Landing Page

Anonymous
Not applicable

Hi Justin -

I was indeed able to capture UTM parameters on a page using the solution you mentioned. However, the issue was we wanted to store the parameters so that if a user left the page without completing a form and later returned, the original referral source would still be captured.  With the official Marketo solution, the parameters are lost if the user navigates away from the page and the form is not submitted.

Anonymous
Not applicable

You rock, dude.  Thanks so much.

SanfordWhiteman
Level 10 - Community Moderator

I just followed you -- could you follow me back so I can send you a DM about this? Like to have an offline convo about this before you spend too much more time.

SanfordWhiteman
Level 10 - Community Moderator

Evan, this is a very nice contribution and I appreciate the effort! I know a lot of people talk about homebrewing their solutions, but they don't post code.

That said, there are some errors/gaps in your code (you knew this was coming!):

  • Your regex doesn't understand boolean query params (where only the key is present, such as the key `markdownEnabled` in the query string ?clientView=100&markdownEnabled&utm_medium=...) and instead concatenates two keys. See http://evangogh.github.io/utm-cookies/?markdown&utm_campaign=amber&utm_source=alpha&utm_medium=apple...
  • You can't rely on window.onLoad() firing before the form is loaded.  If the form must depend on cookies being present, the form load needs to be made dependent on another event's completion. Otherwise you have a race condition and your code will sometimes succeed and sometimes fail.
  • A table object (or array) would be much better to hold the interesting fields, so the configuration is in one place. Then iterate over that object.
  • When iterating over an object, always check hasOwnProperty unless you have an explicit reason to want inherited keys (or if you are using a prototypeless object or POESO).
  • Hard-coding a single domain is problematic because people use domain aliases.  If the same site can be accessed using www,example.com or www.example2.com, you want to ensure that cookies will be set for .example.com in the first case and .example2.com in the second.  To do this, find the shortest private domain by shortening the domain and setting test cookies.
Anonymous
Not applicable

Hi Sanford -

Yes, I was waiting for your response! In fact, I almost mentioned in the post that you could probably write the code much better and answer any questions that might arise much better than I could, but didn't want to put you on the spot like that.

I actually received the code from Marketo's Lead Technical Consultant and tweaked a few things. From all the posts I read on Stack Exchange I figured I needed a different regex, but couldn’t get figure out how to get anything else to work.  For what it's worth, here's the exact code I received from Marketo, in its entirety:

<html>

<p>

// fetch url name value parameters and can create cookie

// url?cookieName=cookieValue

</p>

<script src="//app-abk.marketo.com/js/forms2/js/forms2.min.js"></script>

<form id="mktoForm_1071"></form>

<script>MktoForms2.loadForm("//app-abk.marketo.com", "898-UZL-601", 1071);</script>

<script>

function getQueryParams(qs) {

qs = qs.split("+").join(" ");

var params = {}, tokens,

re = /[?&]?([^=]+)=([^&]*)/g;

while (tokens = re.exec(qs)) {

params[decodeURIComponent(tokens[1])] = decodeURIComponent(tokens[2]);

}

return params;

}

function btnClickFunction() {

var query = getQueryParams(document.location.search);

for (var key in query) {

console.log(key, query[key]);

document.cookie = key + "=" + query[key];

}

var elem = document.getElementById("customCookieField");

elem.value = query["cookieName"];

}

</script>

<button onClick="btnClickFunction()"> set cookie </button>

</html>