Track UTM Parameters in Sitecore Forms

Track UTM Parameters in Sitecore Forms

Are you using Sitecore and need to capture UTM parameters like utm_source and utm_campaign for analytics? In this post, I’ll walk through a clean, practical way to track utm parameters in Sitecore Forms without modifying Sitecore’s pipeline or relying on any heavy customisation.

The Basics: What Are UTMs?

Urchin Tracking Module (UTM) parameters are commonly used to track how users arrive on your site. But if you don’t capture them before a form is submitted, that valuable marketing data can disappear without a trace — something we want to avoid at all costs!

Here are some UTM parameters you may already be familiar with, along with how each is typically used:

  • utm_campaign — Identifies the specific campaign that drove traffic to your site (e.g. big_sale, black_friday, or newsletter_march). Useful for tying traffic to a particular promotion or initiative.
  • utm_content — Distinguishes variations of the same ad or link. You might use this to A/B test CTA buttons (cta_button_red, cta_button_blue) or track different placements (sidebar_link, footer_link).
  • utm_medium — Describes the marketing channel. Common examples include email, cpc, social, or affiliate. It helps group traffic by broad type.
  • utm_source — Specifies where the traffic came from, usually a platform or referrer (e.g. google, facebook, newsletter, linkedin).
  • utm_term — Captures search terms in paid search campaigns. For example, if someone clicked your ad after searching for “software engineer”, this could be set to software+engineer.
  • utm_<custom> — You can add your own custom UTM parameters to track any other context or segmentation relevant to your team. Just make sure your analytics tool or backend understands and logs it properly (e.g. utm_region=apac, utm_version=v2).

Now we’re familiar with what UTMs are and how they’re used, let’s look at how to implement this tracking in Sitecore Forms.

Step 1: Add Hidden UTM Fields in Sitecore

To enable UTM tracking in a specific form:

  1. Open the form in Sitecore Forms Editor.
  2. Add a Hidden field.
  3. Name it to match a UTM parameter you want to capture (e.g., utm_source, utm_campaign, etc).
  4. Repeat the above step for as many standard or custom utms as you need.
  5. Publish the form.

Step 2: Capture and Apply UTM Parameters with JavaScript

We’re going to capture any UTM variables passed to the form using JavaScript. They’ll be stored locally using the browser’s session storage.

Take a look at this self-contained JavaScript snippet you can drop onto any page with a Sitecore form:

document.addEventListener('DOMContentLoaded', () => {
  const formElement = document.querySelector('.sitecore-form form');
  if (!formElement) return;

  const urlParams = new URLSearchParams(window.location.search);

  // Store any utm_<something> parameters
  urlParams.forEach((value, key) => {
    if (key.startsWith('utm_')) {
      sessionStorage.setItem(key, value);
    }
  });

  // Populate form hidden fields with any stored UTM params
  Object.keys(sessionStorage).forEach((key) => {
    if (key.startsWith('utm_')) {
      const storedValue = sessionStorage.getItem(key);
      const input = formElement.querySelector(`input[data-sc-field-name="${key}"]`);
      if (input) input.value = storedValue;
    }
  });

  // Clear UTM data on form submission
  formElement.addEventListener('submit', () => {
    Object.keys(sessionStorage).forEach((key) => {
      if (key.startsWith('utm_')) {
        sessionStorage.removeItem(key);
      }
    });
  });
});

You can place this script in a layout file, partial view, or inline on a specific page—wherever your Sitecore form is rendered. Just make sure it loads after the form HTML.

Here’s what the form does:

  • Detects utm_ parameters in the query string.
  • Stores them in sessionStorage for the duration of the user’s session.
  • Fills in hidden fields when the form loads.
  • Clears the data after submission.

Step 3: Working Example – Try it Yourself

Want to see it in action? Here’s a complete example you can try locally. Save the following HTML as utms.html and open it in your browser. Then add some UTM parameters to the URL and watch them flow through to the form:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>UTM Test Form</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <style>
    body { font-family: sans-serif; padding: 2rem; max-width: 600px; margin: auto; }
    label { display: block; margin-top: 1rem; }
    input[type="text"], input[type="hidden"] { width: 100%; padding: 0.5rem; margin-top: 0.25rem; }
    button { margin-top: 1.5rem; padding: 0.75rem 1.5rem; }
  </style>
</head>
<body>

  <h1>Sitecore UTM Parameter Test</h1>
  <p>Try appending <code>?utm_source=test&utm_campaign=my_campaign</code> to the URL and reload the page.</p>

  <div class="sitecore-form">
    <form>
      <label>
        Name:
        <input type="text" name="name" required>
      </label>

      <!-- Hidden fields for UTM parameters -->
      <input type="hidden" data-sc-field-name="utm_source" name="utm_source">
      <input type="hidden" data-sc-field-name="utm_medium" name="utm_medium">
      <input type="hidden" data-sc-field-name="utm_campaign" name="utm_campaign">
      <input type="hidden" data-sc-field-name="utm_term" name="utm_term">
      <input type="hidden" data-sc-field-name="utm_content" name="utm_content">

      <!-- Optional: example for custom UTM -->
      <input type="hidden" data-sc-field-name="utm_custom" name="utm_custom">

      <button type="submit">Submit</button>
    </form>
  </div>

  <script>
    document.addEventListener('DOMContentLoaded', () => {
      const formElement = document.querySelector('.sitecore-form form');
      if (!formElement) return;

      const urlParams = new URLSearchParams(window.location.search);

      // Store any utm_<something> parameters
      urlParams.forEach((value, key) => {
        if (key.startsWith('utm_')) {
          sessionStorage.setItem(key, value);
        }
      });

      // Populate form hidden fields with any stored UTM params
      Object.keys(sessionStorage).forEach((key) => {
        if (key.startsWith('utm_')) {
          const storedValue = sessionStorage.getItem(key);
          const input = formElement.querySelector(`input[data-sc-field-name="${key}"]`);
          if (input) input.value = storedValue;
        }
      });

      // Clear UTM data on form submission
      formElement.addEventListener('submit', () => {
        Object.keys(sessionStorage).forEach((key) => {
          if (key.startsWith('utm_')) {
            sessionStorage.removeItem(key);
          }
        });
        alert('Form submitted. UTM data cleared from sessionStorage.');
      });
    });
  </script>
</body>
</html>

Once you’ve saved and opened it, append some parameters to the query string and hit enter:

?utm_campaign=summer_sale&utm_custom=hello&utm_extra=world&another_variable=noaction

Once the page loads again, open dev tools and take a look at your local session storage. I’m using Chrome here, but you’ll find similar tooling in most modern browsers:

UTM values stored in Chrome sessionStorage during Sitecore form test.

You can see in the screenshot above that utm variables have been saved to session storage for use in the form. Note that the extra variable called another_variable with the value noaction was not stored because we are restricting by name in the JavaScript.

Also note that the hidden fields in the form have also been populated, but the utm_extra that we don’t want to capture has been intentionally ignored:

Screenshot of Sitecore hidden field UTM parameters.

This method doesn’t interfere with accessibility tools or input focus. Since we’re using hidden fields that Sitecore already expects, there’s no impact on screen readers or keyboard navigation.

Finally, type your name into the input field and submit the form. The hidden fields will have been posted to whichever destination you choose (whether that be an API or back-end code), and cleared from the session storage:

Screenshot of browser having cleared UTM parameters from session storage.

Note: Since this logic works entirely on the client side and doesn’t transmit sensitive data, it’s generally safe. However, always validate data server-side before using it in CRM or analytics integrations.

Evaluating This Approach

Here’s why this approach works well in Sitecore:

  • Simple and lightweight — modern browser support, no extra dependencies.
  • Works with AJAX and multi-step forms; persists across client-side transitions.
  • Secure — relies only on expected hidden fields already defined in the CMS and isn’t blocked by Sitecore’s handling of dynamically-generated form fields.
  • Empowers editors — campaign teams can launch UTM tracking without dev input.

Keep in mind…
If a user lands on one campaign page but completes a different form later in the session, UTM values may be misaligned. You can solve this by adding a form ID to the session key (e.g., utm_source__form123) or scoping UTM capture to specific forms.

Final Thoughts

If you’re working with Sitecore Forms and want a clean way to track UTM data, this method gives you all the flexibility without complicating your architecture. It’s quick to implement, safe with Sitecore’s form handling, and easily testable. Give the example a spin and see how it fits into your own tracking setup.

Have questions or your own tips for UTM tracking in Sitecore? Drop them in the comments — I’d love to see how others are approaching this.

Leave a Reply

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