Global Hola

Global Hola Logo - Horizontal - Blue
Track Web User Source & Journey on Calendly and Contact Us Forms

In the era of data-driven decision-making, understanding the source and journey of your website visitors before they sign up for a service is key to understanding the effectiveness of your marketing campaigns. Recently, I found a pain point in seeing where visitors to our outsourcing company’s website were coming from when booking a Calendly meeting on our site.

Figuring this out was tough. Really tough, especially if you’re not a website developer guru.

My Quote. Yes, that’s me.

Solving this issue took a lot of research and troubleshooting, and I want to make that process easier for other web developers and non-techy people. You don’t need to understand javascript or coding to make this work. You’ll just need to update specific parts of the code variables to make this work for your website, Calendly, and Forminator setup.

So here in this article, let’s go through all the steps for you to easily start tracking where your users came from when they submit a Forminator contact us form or a Calendly booking.

How to Create Your Tracking Links

Before talking about the code and everything, you need to know how to set up your links to start tracking your users’ signup journeys. We’ll be using UTM parameters to track the key variables for your users.

The main tracking parameters you’ll want to be using are:

  • utm_campaign — > Identifies a specific product promotion or strategic campaign. Example: utm_campaign=spring_sale
  • utm_source → Identifies which site sent the traffic, and is a required parameter. Example: utm_source=google
  • utm_medium → Identifies what type of link was used, such as cost per click or email. Example: utm_medium=cpc
  • utm_content → Identifies what specifically was clicked to bring the user to the site, such as a banner ad or a text link. It is often used for A/B testing and content-targeted adsExample: utm_content=logolink
  • utm_affiliate_code → This is if you’re using an affiliate program to track what affiliate program participant sent you the user. Example: utm_affiliate_code=affiliate_mrbeast

Your tracking link must be designed like this:

  • TRACKING LINK = domain + ? + UTM Parameters
  • domain = https://globalhola.com/ or https://globalhola.com/contact/ ← This can be the URL you want your users to first visit.
  • ? ← This is to start your URL parameters. Without it, your link won’t work.
  • UTM Parameters = utm_campaign=medium_howto_series&utm_medium=blog_article&utm_source=medium&utm_content=web_user_tracking_article&utm_affiliate_code=none

Here’s a good website URL example for you to start creating your tracking links: https://globalhola.com/contact/?utm_campaign=medium_howto_series&utm_medium=blog_article&utm_source=medium&utm_content=web_user_tracking_article&utm_affiliate_code=none

How to Track Calendly Bookings Source & Information

In this guide, we’ll dive deep into JavaScript code and setup in your WordPress website that allows you to seamlessly track your visitors’ journey and push these insights into your Calendly bookings & contact us forms in Forminator.

I use Forminator for our website forms because it’s free and flexible. It also easily allows you to create hidden fields to log URL parameters. For that, go to the section below on how to set up your Forminator form to accept and track the fields in hidden fields.

I. Understand The Code

The JavaScript code provided is designed to append selected UTM parameters from your user’s landing page to the URLs of the links on your website. It is particularly focused on the links leading to specified domains. This makes is so that external URLs you’re linking to won’t receive your UTM parameters unless you want them to.

The problem is that if you don’t use this code, your user’s landing page UTM parameters won’t get sent to the other pages that they go to.

Without Code ☹️

User Landing Page: https://globalhola.com/?utm_campaign=cool_campaign&utm_medium=cool_medium&utm_source=cool_source&utm_content=cool_content&utm_affiliate_code=cool_affiliate

2nd Page: https://globalhola.com/contact

Bummer. The UTM parameters don’t get sent to the next pages your user visits on your website. They’ll have to go directly to the specific page with the URL parameters to have this work. Eeks.

With Code 😃

User Landing Page: https://globalhola.com/?utm_campaign=cool_campaign&utm_medium=cool_medium&utm_source=cool_source&utm_content=cool_content&utm_affiliate_code=cool_affiliate

2nd Page: https://globalhola.com/contact?utm_campaign=cool_campaign&utm_medium=cool_medium&utm_source=cool_source&utm_content=cool_content&utm_affiliate_code=cool_affiliate

See the difference? Your UTM parameters will be sent from the initial landing page to all of the next URLs your user visits. Your pages and forms can then read those URL parameters to grab and send them in your forms!

I provide the full code at the bottom here, but here’s a detailed breakdown of each section:

1. Define Your UTM Parameters and Domains

This segment allows you to specify the query parameters and domains that you wish to track. You can customize the parameters and domains according to your needs.

// These are all the domains where you want to add the utm parameters to
var domainsToDecorate =
[
'globalhola.com', // put your website domain here
'calendly.com' // This is where you put a special domain to send URL parameters to.
];

// Here are where you put all of the URL Parameters that you want to track
// The URL query parameters below would work if your link is something like https://globalhola.com/?utm_campaign=business_made_easy&utm_source=linkedIn&utm_medium=web&utm_affiliate_code
var queryParams =
[
'utm_medium',
'utm_source',
'utm_campaign',
'utm_content',
'utm_affiliate_code'
];

2. Capture and Modify Links

The code analyzes all the links on the webpage and checks if they lead to any of the defined domains. If a match is found, it decorates the link by adding the query parameters onto the end of the URL.

var links = document.querySelectorAll('a');

for (var linkIndex = 0; linkIndex < links.length; linkIndex++)
{
for (var domainIndex = 0; domainIndex < domainsToDecorate.length; domainIndex++)
{
if (
links[linkIndex].href.indexOf(domainsToDecorate[domainIndex]) > -1 &&
links[linkIndex].href.indexOf("#") === -1
)
{
links[linkIndex].href = decorateUrl(links[linkIndex].href);
}
}
}

3. Decorate the URLs

The decorateUrl function appends the chosen query parameters to the URL. If the link leads to calendly.com, an additional parameter a4 is prepared, which concatenates the values of the UTM parameters.

// Decorates every clicked on internal URL with the query params
// Creates a special condition for Calendly URL to add the URL parameters to the a4 question
function decorateUrl(urlToDecorate)
{
urlToDecorate = urlToDecorate.indexOf('?') === -1 ? urlToDecorate + '?' : urlToDecorate + '&';
var collectedQueryParams = [];

for (var queryIndex = 0; queryIndex < queryParams.length; queryIndex++)
{
if (getQueryParam(queryParams[queryIndex]))
{
collectedQueryParams.push(queryParams[queryIndex] + '=' + getQueryParam(queryParams[queryIndex]));
}
}


// Add the UTM_source to query string 'a4' only if the URL contains 'calendly.com
var calendly_question = "a4";

if (urlToDecorate.indexOf('calendly.com') > -1)
{
var utm_campaign = getQueryParam('utm_campaign');
if(utm_campaign == null)
{
utm_campaign = "none";
}
var utm_source = getQueryParam('utm_source');
if(utm_source == null)
{
utm_source = "none";
}
var utm_medium = getQueryParam('utm_medium');
if(utm_medium == null)
{
utm_medium = "none";
}

var utm_content = getQueryParam('utm_content');
if(utm_content== null)
{
utm_content = "none";
}

var utm_affiliate_code = getQueryParam('utm_affiliate_code');
if(utm_affiliate_code == null)
{
utm_affiliate_code = "none";
}

var separator_for_parameters = "---";

var question_value = "utm_campaign" + "=" + utm_campaign + separator_for_parameters +
"utm_source" + "=" + utm_source + separator_for_parameters +
"utm_medium" + "=" + utm_medium + separator_for_parameters +
"utm_content" + "=" + utm_content + separator_for_parameters +
"utm_affiliate_code" + "=" + utm_affiliate_code;
collectedQueryParams.push(calendly_question + "=" + encodeURIComponent(question_value));
}

return urlToDecorate + collectedQueryParams.join('&');
}

4. Extract Query Parameters

The getQueryParam function retrieves the value of a specific query parameter from the current URL. It is used within decorateUrl to gather parameter values.

function getQueryParam(name) 
{
if ((name = (new RegExp('[?&]' + encodeURIComponent(name) + '=([^&]*)')).exec(window.location.search)))
return decodeURIComponent(name[1]);
}

Here’s the Full Code All Together

(function() {
var domainsToDecorate = [
'globalhola.com',
'calendly.com' // Add or remove domains (without https or trailing slash)
];

// Add or remove query parameters you want to transfer
var queryParams = [
'utm_medium',
'utm_source',
'utm_campaign',
'utm_content',
'utm_affiliate_code'
];

// Do not edit anything below this line
var links = document.querySelectorAll('a');

// Check if links contain domain from the domainsToDecorate array and then decorate
for (var linkIndex = 0; linkIndex < links.length; linkIndex++) {
for (var domainIndex = 0; domainIndex < domainsToDecorate.length; domainIndex++) {
if (
links[linkIndex].href.indexOf(domainsToDecorate[domainIndex]) > -1 &&
links[linkIndex].href.indexOf("#") === -1
) {
links[linkIndex].href = decorateUrl(links[linkIndex].href);
}
}
}

// Decorates the URL with query params
function decorateUrl(urlToDecorate)
{
urlToDecorate = urlToDecorate.indexOf('?') === -1 ? urlToDecorate + '?' : urlToDecorate + '&';
var collectedQueryParams = [];

for (var queryIndex = 0; queryIndex < queryParams.length; queryIndex++)
{
if (getQueryParam(queryParams[queryIndex]))
{
collectedQueryParams.push(queryParams[queryIndex] + '=' + getQueryParam(queryParams[queryIndex]));
}
}


// Add the UTM_source to query string 'a4' only if the URL contains 'calendly.com
var calendly_question = "a4";

if (urlToDecorate.indexOf('calendly.com') > -1)
{
var utm_campaign = getQueryParam('utm_campaign');
if(utm_campaign == null)
{
utm_campaign = "none";
}
var utm_source = getQueryParam('utm_source');
if(utm_source == null)
{
utm_source = "none";
}
var utm_medium = getQueryParam('utm_medium');
if(utm_medium == null)
{
utm_medium = "none";
}

var utm_content = getQueryParam('utm_content');
if(utm_content== null)
{
utm_content = "none";
}

var utm_affiliate_code = getQueryParam('utm_affiliate_code');
if(utm_affiliate_code == null)
{
utm_affiliate_code = "none";
}

var separator_for_parameters = "---";

var question_value = "utm_campaign" + "=" + utm_campaign + separator_for_parameters +
"utm_source" + "=" + utm_source + separator_for_parameters +
"utm_medium" + "=" + utm_medium + separator_for_parameters +
"utm_content" + "=" + utm_content + separator_for_parameters +
"utm_affiliate_code" + "=" + utm_affiliate_code;
collectedQueryParams.push(calendly_question + "=" + encodeURIComponent(question_value));
}

return urlToDecorate + collectedQueryParams.join('&');
}

// Borrowed from https://stackoverflow.com/questions/831030/
// A function that retrieves the value of a query parameter
function getQueryParam(name)
{
if ((name = (new RegExp('[?&]' + encodeURIComponent(name) + '=([^&]*)')).exec(window.location.search)))
return decodeURIComponent(name[1]);
}
})();

II. How To Implement the Code On Your WordPress Website

Now that we’ve dissected the JavaScript code, it’s time to put it into action on your WordPress website.

1. Download and Install the WP Code Snippets Plugin

Navigate to your WordPress Dashboard and go to “Plugins” > “Add New”. Search for “WP Code Snippets” and install it. This plugin allows you to safely add custom scripts to your WordPress website.

2. Add the Code to Your Header Scripts

Once installed, you’ll find the WP Code Snippets option in your WordPress dashboard. Navigate to it, create a new snippet, and paste your JavaScript code into the Code section. In the “Where to insert the code?” section, select “Header (before closing the header tag)”. Save your changes.

3. Test the Implementation on Your Website & Calendly

It’s time to validate your setup. Open your website and navigate through the links leading to the specified domains that you listed in your domains list. The initial landing page UTM parameters should be added to the URL. Click on the various links on your site, and do a typical user journey to see how the URL parameters get passed from link to link.

III. How To Capture the Data in Calendly

To get this data to your Calendly form, you’ll need to do the following.

1. Create Your Calendly Booking Form

Create your Calendly booking form with all the fields you want your user to be submitting. Add an additional question that has the label “Special Signup Code (Don’t Edit)”. Note what # the question is. In our form below, you can see the question is question #4 (note the a4 in our code). If your question is question #6, you’ll need to update the code for your calendly_question variable to be a6.

2. Set Up The Link on Your Website

After creating your Calendly booking form, make sure the link on your website is the link to your Calendly booking page. For example, on your homepage you might have a button with the link to your Calendly booking page: https://calendly.com/d/z64-p42-cz3/discovery-call. Don’t add any UTM parameters to your link yet as the script will do this automatically for you.

When web visitors come to your page from your special link with the URL parameters, the code will attach the parameters to your URL which will then be sent to your Calendly booking form.

3. Test Test Test

Make sure the code is working and sends the special code to your Calendly booking form by doing some tests via different links.

IV. How To Capture the Data in Forminator Contact Us Forms

To get this data to your Forminator form, you’ll need to set up your form to have hidden fields that store your URL parameters.

1. Create Your Forminator Form with Hidden URL Parameter Fields

Create your Forminator form with hidden URL parameter fields that grab the parameters from the URL. See the image below for how to do that.

Here’s the form. Note the field names (yellow) and that they’re hidden fields (green).
For each field, make sure the default value is Query Parameter and that the Query parameter is set to the query parameter field.

2. Test Test Test

Make sure the code is working and sends the special code to your Forminator form by doing some tests via different links.

V: Capture & Parse the Data in Zapier to Send To Your Lead Tracking Tool

We track all of our new Calendly bookings as leads in our CRM (Zoho CRM). To do this, we need to parse the values from the special sign-up code so that we can send them to our lead fields in Zoho CRM.

1. Set up a Webhook or Trigger to Receive the Data

If you’re using Calendly, you can set up a trigger in Zapier to run on every new Calendly booking. You can also set up a filter 2nd step to make sure your Zap only runs on bookings from the right form.

If you’re doing this via a Forminator form, you’ll need to…

  • Setup the webhook integration in your Forminator plugin
  • Allow your form to use that integration
  • Create a zap with the webhook trigger
  • Copy/paste the webhook link from Zapier into your forms webhook place.
How to Setup a Webhook To Send Forminator Form Data to Zapier

2. (If Calendly) Use Zapier Code (Python) to Parse the Values

Set your Input Data variable to be unformatted_codes, and set the value to be the field value from Calendly.

Next, use the following Python code to parse the special code to separate them into your UTM unique values.

try:
input_string = input_data['unformatted_codes']
except:
print("No input code found")
input_string = "utm_campaign=none---utm_source=none---utm_medium=none--- utm_content=none---utm_affiliate_code=none"

print(input_string)
# Split the input string into individual key-value pairs
pairs = input_string.split('---')

# Initialize an empty dictionary to store the extracted values
output = {}

# Extract the values and store them in the dictionary
for pair in pairs:
if pair:
key, value = pair.split('=')
# If the value is 'none', make it blank
if value.lower() == 'none':
value = ''
# Remove the 'utm_' prefix from the keys
key = key.replace('utm_', '')
output[key] = value

# Wrap the output dictionary in a list
print(output)
output = [output]

3. (Both Calendly & Forminator) Place the Values in Your Fields in Your Lead Tracking System

We use Zoho CRM to track our leads and accounts, so we created special fields in our leads, accounts, and deals modules to track the source of our leads.

TL;DR — Track Your Web User Signup Source in Calendly and Contact Us Forms

This strategy allows you to carry UTM parameters (or any other parameters you choose) across different pages of your website, and send them to Calendly when a user makes a booking. It also allows you to store the values in hidden fields in Forminator or another WordPress forms tools with hidden fields from URL parameter capabilities to track where your form submissions came from.

As a result, you can understand where your visitors come from and how they engage with your website before making an appointment. Remember, data-driven decision-making is key to optimizing your digital marketing strategy.

Happy tracking!