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:
- Stores UTM data in LocalStorage.
- 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.