I’ve written about getting UTM Parameters from the URL when someone visits your website, then using them to add to hidden fields on a form and passing them through to a Lead record in D365. This is a great way to figure out where your Leads are coming from. However, thanks to Ferdinand Ganter, a reader of my blog, I had to rethink things. What about someone that comes to your site with a link that has UTM parameters but then navigates away from that page? The UTM parameters are then stripped away and you are left with nothing. What about times where you want to share a link to a page that doesn’t have a form, but that visitor ends up on one? Wouldn’t you still like to get that information back in to D365? Then read on, this blog is for you!

As a quick recap for anyone wanting to record this info, you will need to make sure you add in some custom fields as these do not exist out of the box. Here you can see my ideal end result, the referrer URL, UTM Source, UTM Medium, UTM Campaign and UTM Content all being captured on a Lead. So make sure you have these fields created first and have them added to your Lead form in D365 so you can then see the values on new Leads created.

Click to view in detail

Again, as a recap, this is what we are referring to… a link posted somewhere online either on social media, sent via an email, linked to from another website etc. that has UTM Parameters passed through. If you are still not sure what I mean, make sure you take a look at this post on Googles Campaign URL Builder. Below you can see a link with the utm_source of linkedin, utm_medium of social, utm_campaign of session_storage_demo and utm_content of personal_account (to indicate the social media post was on my personal profile rather than my company profile.


After someone lands on that URL above, if they then click on another link, the UTM parameters are stripped immediately. So if they then go back to the original page, it would look like this. We want to be able to grab those parameters as soon as they land on the site and store them to use later on. Want to check it out? You can click here to review and submit the form.


Now for this next part, MASSIVE THANK YOU to Greg Kogan who wrote this post here. You can see that what I have used has the script from Greg as the starting point. I’ve modified it to work more for D365 and also added in some logic to also store the referrer URL indicating where someone came from, or if there isn’t one, I set it as ‘N/A’.

Get URL + UTM Parameters with Javascript (Easy!) | Greg Kogan

When visiting a website, there is something called the sessionStorage which can hold on to information for the entire length of the session. This is cleared as soon as the browser is closed. We can utilise this to store that referral information. Another MASSIVE THANK YOU to Ferdinand Ganter again for sharing his findings that relate to links that are clicked on from email sent from Realtime Marketing Journeys where the UTM Parameter functionality has been turned on. This appends #msdynmkt_trackingcontext plus a guid to the end of the URL. We want to make sure if this exists in the URL, it is removed and not included. Otherwise it will add in to last UTM parameter that was included in the URL. Ask your web developer to add this right above the closing body tag in the website. If you use WordPress, this would be in the footer.php file. Without the script below, the parameters from the URL will not be added to the sessionStorage.

  // Check if referrer is already stored in sessionStorage
  var referrer = sessionStorage.getItem("referrer");

  // If it's not stored, get it from document.referrer and store it
  if (!referrer) {
    referrer = document.referrer || "N/A";
    sessionStorage.setItem("referrer", referrer);

  var queryForm = function(settings) {
    var reset = settings && settings.reset ? settings.reset : false;
    var self = window.location.toString();
    // Check for the presence of '#msdynmkt_trackingcontext' in the URL fragment
    if (self.includes("#msdynmkt_trackingcontext")) {
      // Remove the fragment part including '#msdynmkt_trackingcontext'
      self = self.split("#")[0];

    var querystring = self.split("?");
    if (querystring.length > 1) {
      var pairs = querystring[1].split("&");
      for (i in pairs) {
        var keyval = pairs[i].split("=");
        if (reset || sessionStorage.getItem(keyval[0]) === null) {
          sessionStorage.setItem(keyval[0], decodeURIComponent(keyval[1]));

  // Call the queryForm function to process the query parameters

Once that has been taken care of, make sure you add in those new fields to your marketing forms, then make sure they are set to be hidden so the person doesn’t see that information.

Click to view in detail

Once you’ve published the form, take the Javascript you are provided with and add it to your website. Directly underneath that, add in the script provided below. I originally had the script added in to the HTML of the form, but there were challenges getting it to work all the time. The results are more consistent when added directly to the same page as the form script.

The first block creates a function to find the right fields by the label text of the fields you’ve included on the form. This means we don’t need to worry about knowing the database field name or any id that gets attached to the fields when you add them to the form. This makes it much easier to reuse the script on any form you have. The next step finds the right fields based on their name. if you have named your fields the same as mine then you wouldn’t need to change a thing. However, if you have named Referrer URL differently and called it Referrer for example, that is what you would need to include in the script within the double quotes in the line that states let referrerUrlField = findInputByLabelText(“Referrer URL”);. Make any other changes needed to make sure the field names are set correctly for your environment.

Then we get the values that have been stored in the sessionStorage via the script above. If there is nothing stored for the UTM values, I am setting it as ‘N/A’ instead, just so there is something added to the Lead rather than the fields being blank. Finally, the script takes the values set (sessionStorage value or N/A) and adds them to the corresponding field that was found near the start of the script. Perfect!

    // Define the findInputByLabelText function in the global scope
  function findInputByLabelText(labelText) {
    var labels = document.querySelectorAll('label[title="' + labelText + '"]');
    for (var i = 0; i < labels.length; i++) {
      var label = labels[i];
      var inputId = label.getAttribute("for");
      if (inputId) {
        var inputElement = document.getElementById(inputId);
        if (inputElement) {
          return inputElement;
    return null;

  document.addEventListener("d365mkt-afterformload", function() {
    function populateFormFields() {

      //Find the right fields based on their name
      let referrerUrlField = findInputByLabelText("Referrer URL");
      let utmSourceField = findInputByLabelText("UTM Source");
      let utmCampaignField = findInputByLabelText("UTM Campaign");
      let utmMediumField = findInputByLabelText("UTM Medium");
      let utmContentField = findInputByLabelText("UTM Content");

      // Retrieve values from sessionStorage
      let sessionReferrer = sessionStorage.getItem("referrer");
      let sessionUtmSource = sessionStorage.getItem("utm_source") || "N/A";
      let sessionUtmCampaign = sessionStorage.getItem("utm_campaign") || "N/A";
      let sessionUtmMedium = sessionStorage.getItem("utm_medium") || "N/A";
      let sessionUtmContent = sessionStorage.getItem("utm_content") || "N/A";

      // Populate the form fields with sessionStorage values
      referrerUrlField.value = sessionReferrer;
      utmSourceField.value = sessionUtmSource;
      utmCampaignField.value = sessionUtmCampaign;
      utmMediumField.value = sessionUtmMedium;
      utmContentField.value = sessionUtmContent;


If you want to make sure the values are actually being added to the session storage, you can right click on your webpage and click Inspect.

Click to view in detail

Then click on Application. If you don’t see it right away, click on the plus sign at the end of the tabs and you should find it there.

Click to view in detail

Then go in to Storage, then Session storage and you should see your website listed. Click on that and the keys and values should be visible. If you then click on a link to another page on your website, you should still see the values stored. Go back to the page with your form and the values should be populated in to the correct fields.

Click to view in detail

Now submit your form to test it, and in a perfect world with everything done right, you should see the values added to the Lead. Brilliant! Want to check it out? You can click here to review and submit the form.

Click to view in detail

Check out the latest post:
Predefined Placeholder Access In Customer Insights - Journeys

D365 Marketing Weekly
Have you seen the D365 Marketing Weekly newsletter yet?
A weekly issue covering features, functionality and news on the topic of Marketing, specifically covering Dynamics 365 Marketing and other interesting tools and tips for anyone interested in the subject.
Subscribe Here
This is just 1 of 456 articles. You can browse through all of them by going to the main blog page, or navigate through different categories to find more content you are interested in. You can also subscribe and get new blog posts emailed to you directly.

4 thoughts on “Using Browser Session Storage To Add Referrer and UTM Parameters To Leads

  1. Hi, this solution seems pretty valid for scenarios where all data analysis is done in D365 or you have journeys that you wanna modify based on campaign. I have implemented this as non-normalized string. All the UTM and possibly other HTTP Get parameters into just one text field. The javascript side looks pretty similar and the analysis phase then requires, for example in PowerBI ”split by delimiter” in order to get those as slicers/legends. Im not quite sure if UTM is here to stay but full text capture of session attributes for sure is.

  2. Hi,

    Thanks for the article, very useful.

    Whilst I like the approach, are there any issues with data privacy/GDPR? Whilst the user has to submit the form to send the data, is there any issue storing information within the session storage?

    1. Hi Andy, I am NOT a lawyer so wouldn’t ever comment on or make recommendations on GDPR. However, you aren’t storing any personal data, and by using sessionStorage, it’s removed when the browser is closed. I would consult your legal team to be sure it’s right for you, and also consider updating your terms or privacy policy before using them.

Leave a Reply

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