Capture UTM data with Calendly

78 views Asked by At

I've been struggling with this one for a while. Calendly stores UTM data automatically when it's in the "data-url." However, if someone came to the site, and changes pages then it loses the UTM data and Calendly doesn't capture it. I have to find a way to make this data available so I can capture it when someone books a call.

Therefore, I built a piece of code that does the following:

  1. Stores UTM data in LocalStorage.
  2. When embedding Calendly on the site, I include a piece that appends the data-url to include the UTM data that was stored.

The first time I did this, the Calendly would take very long to load due to the extra code, which isn't ideal. I changed the code to be seperate so that the embed code isn't so "heavy," but then I realized that storing it in LocalStorage isn't great, because then the Calndly Embed doesn't work in incognito or private windows. I also tried storing it as cookies instead, but the issue remained.

Does anyone have a simple way for me to store this data so it works accross subdomains and can be added to the Calendly Embed code without making the code too heavy?

P.S. I can't append the data-url attribute afterward, as then Calendly doesn't capture the data. So, it needs to be happen the same time that the embde code loads.

Here's the code:

1.

<script>
function getUTMParameters() {
  var search = location.search.substring(1);
  var params = {};
  if (window.URLSearchParams && URLSearchParams.prototype.get) {
    var searchParams = new URLSearchParams(search);
    params = {
      utm_source: searchParams.get('utm_source'),
      utm_medium: searchParams.get('utm_medium'),
      utm_campaign: searchParams.get('utm_campaign'),
      utm_term: searchParams.get('utm_term'),
      utm_content: searchParams.get('utm_content'),
      gclid: searchParams.get('gclid'),
      fbclid: searchParams.get('fbclid')
    };
  } else {
    // Fallback for browsers that do not support URLSearchParams
    search.split('&').forEach(function(part) {
      var item = part.split('=');
      params[item[0]] = decodeURIComponent(item[1]);
    });
  }
  return params;
}

// Check if UTM parameters are already set, if not, store them in localStorage
var currentUtmParams = getUTMParameters();
var storedUtmParams = localStorage.getItem('utmParams') ? JSON.parse(localStorage.getItem('utmParams')) : {};

// Update only if new UTM parameters exist
Object.keys(currentUtmParams).forEach(function(key) {
  if (currentUtmParams[key] !== null) {
    storedUtmParams[key] = currentUtmParams[key];
  }
});

localStorage.setItem('utmParams', JSON.stringify(storedUtmParams));
  
</script>
<script>
function updateCalendlyLink() {
    var calendlyWidget = document.querySelector('.calendly-inline-widget');
    if (!calendlyWidget) return;

    var baseCalendlyUrl = 'https://calendly.com/zima-media/consultation?hide_event_type_details=1&hide_gdpr_banner=1&primary_color=ff9900';
    var storedUtmParams = JSON.parse(localStorage.getItem('utmParams') || '{}');
    var utmQueryString = Object.keys(storedUtmParams).length > 0 ? '&' + new URLSearchParams(storedUtmParams).toString() : '';
    calendlyWidget.setAttribute('data-url', baseCalendlyUrl + utmQueryString);
}

document.addEventListener('DOMContentLoaded', updateCalendlyLink);
</script>

Calendly embed

<!-- Calendly inline widget begin -->
<div class="calendly-inline-widget" style="min-width:320px;height:700px;"></div>
<script type="text/javascript" src="https://assets.calendly.com/assets/external/widget.js" async></script>
<!-- Calendly inline widget end -->

This works on normal tabs, but not private ones.

0

There are 0 answers