When working on digital marketing campaigns, tracking the source of your traffic is crucial for measuring the effectiveness of your efforts.
Capturing UTM parameters from URLs and storing them until a user converts is one effective method.
In this step-by-step guide, we’ll walk you through capturing UTM parameters on Webflow websites without any third-party plugins, storing them in the browser’s local storage, and ensuring they persist until conversion without needing HubSpot API calls.
This method leverages HubSpot’s built-in capabilities to scan URLs for UTM parameters and attach them to hidden form fields when found.
This way, we achieve a seamless setup without overly complex coding.
This method is suitable for any type of website.
In our case, the website was built on Webflow, so we had to adapt it accordingly.
Depending on your setup, you might need to make specific adjustments to accommodate your configuration properly.
Step 1: Capture UTM Parameters from the URL
First, we need a function that extracts UTM parameters from the URL.
/ * ------------ Pass UTM parameters to user's Cookie ------------ * //
function () { // Helper function to get URL parameters
function getUTMParams() {
const params = new URLSearchParams(window.location.search);
const utmParams = {};
params.forEach((value, key) => {
if (key.startsWith('utm_')) {
utmParams[key] = value;
}
});
return utmParams;
}
Step 2: Store UTM Parameters in Local Storage
Once captured, store the UTM parameters in the browser’s local storage to ensure persistence. In this case we have also added a 60 day expiration date.
// Save UTMs to local storage for 60 days
function saveUTMsToLocalStorage(utmParams) {
const now = new Date().getTime();
const expiry = now + 60 * 24 * 60 * 60 * 1000; // 60 days in milliseconds
const data = {
params: utmParams,
expiry: expiry
};
localStorage.setItem('utm_data', JSON.stringify(data));
}
Step 3: Retrieve Stored UTM Parameters
To utilize the stored UTM parameters, create a function to retrieve them from local storage. This function also checks if 60 day expiration period hasn't passed.
// Load UTMs from local storage if still valid
function loadUTMsFromLocalStorage() {
const storedData = localStorage.getItem('utm_data');
if (storedData) {
const data = JSON.parse(storedData);
const now = new Date().getTime();
if (now < data.expiry) {
return data.params;
} else {
localStorage.removeItem('utm_data');
}
}
return null;
}
Step 4: Clean up URL
Remember, the HubSpot cookie only captures UTMs when they are present in the URL. Therefore, for pages without conversion forms, we can leave the URL field clean of UTMs until the user is redirected to the required page, allowing the HubSpot cookie to capture the UTM parameters where needed. The goal here is to keep URLs clean in the browser’s address bar so that, if a user shares the link elsewhere, any additional referral actions won’t interfere with the initial UTM tracking information.
// Remove UTMs from URL without reloading the page
function removeUTMsFromURL() {
const url = new URL(window.location.href);
url.searchParams.forEach((value, key) => {
if (key.startsWith('utm_')) {
url.searchParams.delete(key);
}
});
window.history.replaceState({}, document.title, url.pathname + url.search);
}
Step 5: Check if there is a HubSpot form
This function checks if there is a HubSpot form on the page. Remember that UTMs will only populate on pages containing a HubSpot form, keeping the link clean on all other pages.
/* ------------ Append UTM Parameters to Internal Links ------------ */
// Check if current page contains .hbspt-form
function pageContainsHbsptForm() {
return document.querySelector('.hbspt-form') !== null; //.hbspt-form - is the HubSpot native class which we check in order to see if there is a form on the page
}
Step 6: Populate UTMs in URL if HubSpot form presented
Once we confirm that a HubSpot form is present on the page, the UTMs are retrieved from the user's local storage and added to the URL. This way, the HubSpot cookie can capture them when the user ultimately converts.
// Populate UTMs from local storage if present on pages with .hbspt-form
function populateUTMsFromLocalStorage() {
const utmParams = loadUTMsFromLocalStorage();
if (utmParams && pageContainsHbsptForm()) {
const url = new URL(window.location.href);
Object.keys(utmParams).forEach(key => {
url.searchParams.set(key, utmParams[key]);
});
window.history.replaceState({}, document.title, url.pathname + '?' + url.searchParams.toString());
}
}
Step 7: Clean Up Expired UTM Parameters
We set up this function to delete all UTM information from the local page once the user arrives at a specific page, such as a thank-you page, after converting via a HubSpot form.
// Fully delete UTMs and reload page
function handleThankYouPage() {
const isThankYouPage = window.location.pathname.includes('/your-url');
if (isThankYouPage) {
localStorage.removeItem('utm_data');
if (!sessionStorage.getItem('utm_reloaded')) {
sessionStorage.setItem('utm_reloaded', 'true');
window.location.reload();
}
}
}
Step 8: Initialize the Script
Finally, initialize the script to handle all the logic.
// Main script execution
(function main() {
const utmParams = getUTMParams();
if (Object.keys(utmParams).length > 0) {
saveUTMsToLocalStorage(utmParams);
}
// Remove UTMs from URL if .hbspt-form is not present
if (!pageContainsHbsptForm()) {
removeUTMsFromURL();
}
// Populate UTMs on pages with .hbspt-form
populateUTMsFromLocalStorage();
// Handle thank-you page logic
handleThankYouPage();
})();
Complete Code for Passing UTM Parameters into HubSpot Form's Hidden Fields in Webflow
Here's the complete code for passing UTM parameters into HubSpot form's hidden fields on the Webflow website.
Simply copy and paste this code into your Webflow' Custom Code footer section, do adjustments for your specific case and publish it.
You can test the Local Storage using Google Chrome's Inspect feature.
To check the Form Submission, please go to your Hubspot Dashboard.
/* ------------ Pass UTM parameters to user's Cookie ------------ */
(function () {
// Helper function to get URL parameters
function getUTMParams() {
const params = new URLSearchParams(window.location.search);
const utmParams = {};
params.forEach((value, key) => {
if (key.startsWith('utm_')) {
utmParams[key] = value;
}
});
return utmParams;
}
// Save UTMs to local storage for 60 days
function saveUTMsToLocalStorage(utmParams) {
const now = new Date().getTime();
const expiry = now + 60 * 24 * 60 * 60 * 1000; // 60 days in milliseconds
const data = {
params: utmParams,
expiry: expiry
};
localStorage.setItem('utm_data', JSON.stringify(data));
}
// Load UTMs from local storage if still valid
function loadUTMsFromLocalStorage() {
const storedData = localStorage.getItem('utm_data');
if (storedData) {
const data = JSON.parse(storedData);
const now = new Date().getTime();
if (now < data.expiry) {
return data.params;
} else {
localStorage.removeItem('utm_data');
}
}
return null;
}
// Remove UTMs from URL without reloading the page
function removeUTMsFromURL() {
const url = new URL(window.location.href);
url.searchParams.forEach((value, key) => {
if (key.startsWith('utm_')) {
url.searchParams.delete(key);
}
});
window.history.replaceState({}, document.title, url.pathname + url.search);
}
// Check if current page contains .hbspt-form
function pageContainsHbsptForm() {
return document.querySelector('.hbspt-form') !== null;
}
// Populate UTMs from local storage if present on pages with .hbspt-form
function populateUTMsFromLocalStorage() {
const utmParams = loadUTMsFromLocalStorage();
if (utmParams && pageContainsHbsptForm()) {
const url = new URL(window.location.href);
Object.keys(utmParams).forEach(key => {
url.searchParams.set(key, utmParams[key]);
});
window.history.replaceState({}, document.title, url.pathname + '?' + url.searchParams.toString());
}
}
// Fully delete UTMs and reload page
function handleThankYouPage() {
const isThankYouPage = window.location.pathname.includes('/your-link');
if (isThankYouPage) {
localStorage.removeItem('utm_data');
if (!sessionStorage.getItem('utm_reloaded')) {
sessionStorage.setItem('utm_reloaded', 'true');
window.location.reload();
}
}
}
// Main script execution
(function main() {
const utmParams = getUTMParams();
if (Object.keys(utmParams).length > 0) {
saveUTMsToLocalStorage(utmParams);
}
// Remove UTMs from URL if .hbspt-form is not present
if (!pageContainsHbsptForm()) {
removeUTMsFromURL();
}
// Populate UTMs on pages with .hbspt-form
populateUTMsFromLocalStorage();
// Handle thank-you page logic
handleThankYouPage();
})();
})();
/* ------------ End Pass UTM parameters to user's Cookie ------------ */
Conclusion
By following these steps, you can effectively capture, store, and maintain UTM parameters in a user's browser storage until they convert.
This approach does not require any API calls, leveraging HubSpot’s built-in cookies to scan the URL for UTM parameters and attach them to hidden fields.
This ensures a seamless and efficient tracking setup for your digital marketing campaigns.
Be sure to email us at hi@ubunzo.com if you have any suggestions or would like to chat about this topic further.
This is an experimental solution we developed and decided to share with others who might face the same issues.
It's not ideal, and we will most likely update this code in the near future. For now, it works and meets our needs.
Hopefully, it will save you some time as well!
FAQ
Q: Why is tracking UTM parameters important for digital marketing campaigns?
Answer:
Tracking UTM parameters helps measure the effectiveness of your marketing efforts by identifying the source of your traffic, which is crucial for understanding which channels drive the most conversions.
Q: What are UTM parameters?
Answer:
UTM parameters are tags added to a URL to track the performance of campaigns and content across different traffic sources.
Q: How can I capture UTM parameters on a Webflow website?
Answer:
You can capture UTM parameters by using a custom JavaScript function to extract them from the URL.
Q: How do I store UTM parameters in the browser’s local storage?
Answer:
Once captured, use a JavaScript function to store the UTM parameters in the browser’s local storage to ensure they persist until the user converts.
Q: How can I retrieve stored UTM parameters?
Answer:
Create a function to retrieve the UTM parameters from local storage when needed.
Q: How do I include UTM parameters in Hubspot form submissions?
Answer:
Populate URL ending with UTM parameters from Local Storage so the Hubspot Cookies will automatically populate their hidden form fields with the retrieved UTM parameters to ensure they are included in form submissions.
Q: How can I maintain UTM tracking across internal navigation?
Answer:
Append UTM parameters to all internal links to retain tracking across multiple user sessions and internal navigation.
Q: Can I use this method without any third-party plugins?
Answer:
Yes, this method leverages HubSpot’s built-in capabilities and does not require any third-party plugins or API calls.
Q: What is the complete code for this setup?
Answer:
The complete code can be copied and pasted into your Webflow's Custom Code footer section. Be sure to publish it and test the functionality using a test query at the end of your URL.
Q: Where can I find further assistance or provide feedback?
Answer:
Feel free to email us at hi@ubunzo.com if you have any suggestions or would like to discuss this topic further.
Subscribe to receive the latest blog posts to your inbox every week.