Capture UTM Parameters in a Cookie and pass their values to forms

Landing pages may not always have a form. And even if they do, landing pages may not always be the last seen page before a conversion. So, we use UTM tags to determine where the conversions came from. This guide demonstrates how UTM values of a navigating user can be captured into your form submissions.

Many CRM forms have an innate ability to capture the UTMs with form submission data (using “hidden fields”) e.g. in Hubspot you could add UTM related hidden fields and when a user lands on the page, Hubspot’s standard Javascript springs into action, extracts UTM parameter values from the URL and fill them into the hidden fields.  The method, in most cases works, but does not account for the user navigating away from the landing page.

UTM values, however. get sent to GA4 irrespective of user navigation. If you are analyzing attribution in GA4, you do not need this. However, if your goal is to analyze attribution in Hubspot or similar tools, this guide is for you.

Cookie Permissions

Most likely you may not have to separately take permissions for this cookie in your consent management platform since this falls under Marketing and Statistics permissions and assuming you are already taking consent for those. However, check with your legal team anyway.

Let’s start with an overview to set expectation. Also find below a table of contents, if you want to skip sections

Short summary

First of all, this is a guide to reach our goal via Google Tag Manager. For non-GTM implementations where you just want to make changes to your website code, you can simply add the Javascripts. It’s actually way simpler to be honest.

This implementation will, however, involve:

  1. Adding hidden fields to your forms to pass UTM parameters
  2. Adding 2 custom HTML tags in your Google Tag Manager account

Note that we are using ActiveCampaign for this demo but the same principles shall apply to almost all email marketing platforms.

You should change the names we assign to various tags, variables and hidden fields according to your internal naming conventions. We’ve used the following:

    1. Cookie name: utm_params
    2. Hidden form fields: utm_source, utm_medium, utm_campaign, utm_content, utm_term
    3. Custom HTML tag names:
      1. UTM Tag - Extract and Store in a Cookie
      2. UTM Tag - Extract from cookie & Pass into Form

Also note that if you change any names here, you’ll have to update the associated Javascripts accordingly. 

Use the comments within the Javascript to know the points where you’ll have to update

Having the logistics out of the way, lets get started.

Process overview

The process is fairly simple but writing it all down is lengthy. So, please do not get overwhelmed by the length of this article. It is merely a lot of words but not that much work. It is a simple guide for even non-programmers.

The Cookie Dough (read Javascript)

The way we make cookies is via Javascript. So we’ll need chunks of Javascript code to get everything in place. The process itself is simple:

  1. Extract UTM Parameter Values from the URL: First, we’ll extract UTM parameters from the URL when a user visits our website.
  2. Store UTM Parameter Values in a Cookie: Once extracted, we’ll store these parameters in a cookie.
  3. Retrieve UTM Parameter Values from the Cookie: As the user navigates through the site, we can retrieve the UTM parameters from the cookie and use them as needed.

Tools needed

  1. Forms/CRM: First we make a slight change to your forms by adding 5 hidden fields – one per UTM. In the example below, we’ll use an ActiveCampaign form but the implementation will apply the same way to any other platform.
  2. Google Tag Manager (GTM): If you do not have access to your website code, you could easily use Google Tag Manager to do this for yourself. Needless to say, you need access to GTM. By the way, Simo Ahava also has a Tag template called “Persist UTM Campaign Data” that’ll help you extract and store UTMs in a cookie.
  3. Website Code: If you want to add this directly to your wordpress websites or sites built on other CMSs, make sure you can insert Javascripts in your website.

Implementation

1. Form Changes: Add hidden fields to your form

This will be a big pain if you have a lot of forms already created. Unfortunately there is no escape from this – just like if we were to capture additional information, we have to update the form. So is in this case. See below how we add the 5 hidden fields to an ActiveCampaign form and name them quite obviously as
utm_source
utm_medium
utm_campaign
utm_content
utm_term

2. Google Tag Manager Changes

To populate the hidden fields we added in your form with the UTM values, we first need to extract the values from your URLs. Once extracted, we store the values in a cookie. We do that using a GTM tag as explained below.

Custom HTML tag 1: We’ll call it “UTM Tag – Extract and Store in a Cookie” but that doesn’t matter, call it anything you want. 

Paste the following Javascript into the code. The JS is nothing but contains a function that’ll extract UTM values from the URL of a page that contains UTM parameters.

    function getUTMParameters() {
        var urlParams = new URLSearchParams(window.location.search);
        var utmParams = {};
        ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content'].forEach(function(param) {
            if (urlParams.has(param)) {
                utmParams[param] = urlParams.get(param);
            }
        });
        return utmParams;
    }

Achtung! 🙂 The tag is still not complete as we’ll add the cookie storage script in the same tag

Cookie Storage

Right under the above javascript, add the following:

        function setCookie(name, value, days) {
        var d = new Date();
        d.setTime(d.getTime() + (days * 24 * 60 * 60 * 1000));
        var expires = "expires=" + d.toUTCString();
        document.cookie = name + "=" + value + ";" + expires + ";path=/";
    }

    function storeUTMParametersInCookie(utmParams) {
        var utmString = JSON.stringify(utmParams);
        setCookie('utm_params', utmString, 30); // Store for 30 days
    }

    var utmParams = getUTMParameters();
    if (Object.keys(utmParams).length > 0) {
        storeUTMParametersInCookie(utmParams);
    }


Your full custom HTML tag will look like:

        
    function getUTMParameters() {
        var urlParams = new URLSearchParams(window.location.search);
        var utmParams = {};
        ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content'].forEach(function(param) {
            if (urlParams.has(param)) {
                utmParams[param] = urlParams.get(param);
            }
        });
        return utmParams;
    }

    function setCookie(name, value, days) {
        var d = new Date();
        d.setTime(d.getTime() + (days * 24 * 60 * 60 * 1000));
        var expires = "expires=" + d.toUTCString();
        document.cookie = name + "=" + value + ";" + expires + ";path=/";
    }

    function storeUTMParametersInCookie(utmParams) {
        var utmString = JSON.stringify(utmParams);
        setCookie('utm_params', utmString, 30); // Store for 30 days
    }

    var utmParams = getUTMParameters();
    if (Object.keys(utmParams).length > 0) {
        storeUTMParametersInCookie(utmParams);
    }




Trigger

It’s time to add a trigger. We’ll add the “All Pages” trigger.

Save your tag.

Note 1: Notice the red highlighted part in the code. This code sets the cookie for 30 days but you can change it to as many days you like. The name given to the cookie here is utm_params. Change that to anything you like but remember to update the second tag based on this name you assign.

Note 2: You could also extract the parameter values by creating 5 URL variables as shown below. This is, of course, more straightforward and lets you use individual values separately. 

However, this just means more work. But the custom HTML tag will still have to be created for storing the information in a cookie. So, since we’re creating a custom HTML tag anyway, why not just use the same tag to extract the values too. In this guide, we use only the custom HTML tag.

What’ve we got so far?

This tag is now set to fire on all pages and will look for any UTM values in the URL and store them in a cookie called “utm_params”. Feel free to change the name of this cookie to whatever you like – it’s entirely up to you.

Part 1 is done. Part 2 is about retrieving the cookie information wherever you want and doing your magic.

In this guide, our goal is to pass them into a form’s hidden fields and we are using an ActiveCampaign form. 

We’re not done with the tags. We still have one more custom HTML tag to create in Google Tag Manager to make sure the cookie that we stored earlier can now be retrieved, extracted and passed into the hidden fields of our forms. 

In case a value is not found, the hidden fields will be submitted with blank values.

Custom HTML tag 2: We’ll call it “UTM Tag – Extract from cookie & Pass into Form” but that doesn’t matter, call it anything you want. 

Here is the Javascript that’ll go in this (note – how we are looking for utm_params cookie and passing the values into our hidden fields named in a certain way). In case you have different naming, update the javascript accordingly. 

    function getCookie(name) {
        var nameEQ = name + "=";
        var ca = document.cookie.split(';');
        for(var i = 0; i < ca.length; i++) {
            var c = ca[i];
            while (c.charAt(0) === ' ') c = c.substring(1, c.length);
            if (c.indexOf(nameEQ) === 0) return c.substring(nameEQ.length, c.length);
        }
        return null;
    }

    function getUTMParametersFromCookie() {
        var utmString = getCookie('utm_params');
        if (utmString) {
            return JSON.parse(utmString);
        }
        return {};
    }

    document.addEventListener('DOMContentLoaded', function() {
        var utmParams = getUTMParametersFromCookie();
        var utmFields = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_content', 'utm_term'];

        utmFields.forEach(function(utmField) {
            var hiddenField = document.querySelector('input[type="hidden"][data-name="' + utmField + '"]');
            if (hiddenField && utmParams[utmField]) {
                hiddenField.value = utmParams[utmField];
            }
        });
    });

Check the red highlighted code parts: The first one is the cookie name. Update this if you have used any other cookie name in the first tag.

Check the blue highlighted code parts: This is how ActiveCampaign form fields will be updated. If you are using any other form, please write in the comments and we’ll try to help you. But this code should work for any ActiveCampaign form as long as you use the same names for your hidden fields.

Trigger: Add a trigger again for “All pages”. In this case, we’re keeping it simple to fire the tag on all pages but if you can dynamically identify pages that contain a form, use that as a trigger so tags are not fired when not needed.

Testing

To simply test your implementation, go to GTM preview mode, add UTM parameters to your test URL and go to the page. Now, navigate to a different page so your UTMs no longer show in the URL. Come back to your original page. Go to “view source” and check the value in the hidden fields, you should see the UTM values you originally passed into the URL.

See our test result below. We’ve used the following utm parameters

?utm_source=test-source&utm_medium=test-medium&utm_campaign=test-campaign&utm_content=test-content&utm_term=test-keyword

Notice how the hidden fields are now populated with the values we passed. Yipee!

When you submit the form, these will be available in the contact record to run your automations as you like. For ex – sending users based on UTM values to different automations 😉

Pro tip: We would encourage you to also pass an extra hidden field to store GA client ID for all form submissions. This may come in handy when you want to track email opens in GA4 (yes you can do that with our pixel generator).

Benefits – How does it all matter?

There are multiple benefits of doing so but let’s highlight just a couple of them here for the sake of brevity and value.

Personalizing User experience

You can personalize user experience both on your website and in your marketing automations.

A user clicks on an Ad with UTM parameters e.g. utm_source=google, utm_medium=cpc, utm_campaign=spring_sale.

The website can display personalized content or offers relevant to the holiday offer throughout the user’s session, enhancing the likelihood of conversion.

Attribution Analytics and Reporting

They browse multiple pages on the website before submitting your form.By storing UTM parameters in a cookie, you can accurately attribute the sale to the specific campaign.

This is a no-brainer. With this implementation, you are able to generate attribution reports even in your marketing platform if your platform does not offer that out-of-the box.

Other benefits 

You could also attribute affiliate performance, cross-device tracking and/or create retargeting/remarketing lists – with a little bit of creativity you could level-up your marketing game.

Congratulations!  🙂

You no longer have to worry about losing UTM parameters.

Don’t forget to publish your GTM container!

Let us know in the comments if you face any trouble – we’ll be happy to assist you 😉

If you encounter issues with thank you page refreshes counting your submissions multiple times, check out our guide on how to avoid page refreshes counting conversion twice through Google Tag Manager.

0 Comments

    Leave a Reply