GA4, Google Tag Manager

Calendly to Google Analytics (GA4) Integration

abstract blurred keyboard

A Somewhat Simple Recipe to Track Calendly Bookings via GTM Events in & GA4

There are many articles out there touting Calendly conversion tracking. Calendly even has their own native GA integration that’s super simple to set up. However, it has a few major flaws:

  1. It fires events in your Google Analytics property, but does not attribute source, medium, campaign, nor any other acquisition metric. 
  2. It can only connect to one property. What if you have one Calendly account working across multiple GA properties? No luck!
  3. Using UTMs, you can pull values from the URL with JavaScript. However, this comes with the enormous downside of only working if users convert on the same page they landed on — not to mention it’s complicated to set up. 

In this guide, we’ll show you how to track Calendly bookings in Google Analytics with all the attribution you would expect—source, medium, campaign, and any other details. As a bonus, since this method is based on Google Tag Manager, you can tie the same events to Facebook pixel conversion tags. 

How to set up Calendly conversion tracking

Note: This post has been updated to include instructions for tracking Calendly events in GA4.

This guide will give you the tools to push Calendly events into the dataLayer, and use GTM to pick up those events and send them to Google Analytics. If that sounds complicated, it is. But my team has done the hard work to set up all the tools for you. 

Setting up tracking will require:

  1. Importing our GTM container with the Calendly Tags and Triggers.
  2. Modifying the Calendly embed code on each page where you want to track the events.
  3. Modifying the custom HTML tag in our recipe to match your div ID in step 2, and your Calendly URL.
  4. Updating the imported tags to reference your GA4 measurement ID
  5. Testing and debugging.
  6. Configuring Events as Conversions in GA4

Step 1: Importing our Tag Manager Recipe

This is the easy part. If you haven’t imported a GTM container before, it’s a simple process. 

  1. First, download our GTM recipe file. Visit the link, right click and hit “Save as…”
  2. Then in Google Tag Manager, click admin from the top navigation.
  3. In the Container section, click Import Container.
  4. Choose the file you just downloaded to import and select to add to your existing workspace.
  5. You’ll next need to choose Overwrite or Merge. Select Merge. You will then need to select whether to overwrite or rename conflicting tags. To be safe, select Rename
  6. In the import preview, you should see 4 new tags and 3 new triggers.
this is what your GTM import should look like
  1. Click confirm

Tags included:

  • cHTML – Calendly Event Listener: This tag has the JavaScript that pulls events from Calendly and pushes them into the dataLayer where GTM can “listen” to them. 
  • Event – Calendly View: This will fire an event each time your Calendly widget is viewed.
  • Event – Calendly Pick Date: This will fire an event each time a user selects a specific time and date for a meeting.
  • Event – Calendly Booking: This will fire an event when a user completes a booking. We recommend tying this event to a goal or conversion (covered in Step 6 of this guide).

Triggers included:

  • CE – event_type_viewed: Listens for event_type_viewed from the dataLayer.
  • CE – date_and_time_selected: Listens for date_and_time_selected from the dataLayer.
  • CE – event_scheduled: Listens for event_scheduled from the dataLayer.

Not included in the import is a Google Analytics variable, because you should reference your own. The GA4 event tags reference a dummy ID. See step 4 to update to reference your own measurement ID.

Also, Calendly Event Listener tag will need a page view trigger (covered in Step 3.1 of this guide). That page view trigger will need to be set up to map to where you embed the Calendly widget on your website. 

Step 2: Modify your Calendly embed code

According to Calendly’s advanced embed options, we need to modify the embed code to add an extra div ID, and then in step three, reference that new div ID in our custom JavaScript. Don’t worry, it isn’t as complicated as it sounds.

<div id="custom-calendly-test-3" data-url="https://calendly.com/YOURLINK"><script type="text/javascript" src="https://assets.calendly.com/assets/external/widget.js" async></script></div>

In the above code, note the id=”custom-calendly-test-3” code. This is the modification required. The ID you choose can be anything as long as you reference it in the following step. 

Step 3: Modify the Calendly Event Listener tag

Next, edit the imported cHTML – Calendly Event Listener tag to match the div ID you created in the previous step. Also, make sure to match the URL to your actual Calendly event URL.

<script>
jQuery(document).ready(function(){
if(jQuery('#custom-calendly-test-3').length){
Calendly.initInlineWidget({
 url: 'https://calendly.com/change-this-to-match-your-link,
 parentElement: document.getElementById('custom-calendly-test-3'),
 prefill: {},
});}});
function isCalendlyEvent(e) {
  return e.data.event &&
         e.data.event.indexOf('calendly') === 0;
};
window.addEventListener(
  'message',
  function(e) {
    if (isCalendlyEvent(e)) {
var elem = jQuery(this).get(0);
var dataLayerObject = {
'event': "custom_event." + e.data.event,
'gtm.element': elem,
'gtm.elementClasses': elem.className || "",
'gtm.elementId': elem.id || "",
'gtm.elementTarget': elem.target || "",
'gtm.elementUrl': elem.href || elem.action || "",
};     
      dataLayer.push(dataLayerObject);
    } });
</script>

Step 3.1: Create a page view trigger

This tag will need a trigger to fire. If your Calendly widget is embedded on all pages you can use the default All Pages trigger. If the Calendly widget is embedded on only a handful of pages, you should create a pageview trigger to match only those URLs. 

For example, if the same Calendly widget is embedded on a /free-demo page and a /schedule-meeting page, then you could create a matching regex pageview trigger to fire with the following conditions:

Your pageview trigger should fire on all URLs where you calendly event is embedded

Step 4: Update the imported GA4 event tags to reference your GA4 measurement ID

The imported tags have a placeholder GA4 measurement ID of G-00000000. Replace that measurement ID by referencing your own GA4 config tag or by manually entering your measurement ID. To find your measurement ID navigate to Admin > Data Streams > Click to view your data stream.

Step 5: Test and debug your container

Now that you have the recipe imported and tags modified to match your Calendly URL, it’s time to test and debug. Preview your container in the new window. You should see the Calendly events firing on pages based on the page view trigger you set up.

Your debug in GTM should show custom_event firing in the summary along with your tag.

Test that all three of your Event tags are firing when you interact with Calendly:

  • Calendly View fires on views of the widget
  • Calendly – Pick Date fires upon selecting a time and date
  • Calendly – Booking fires upon scheduling a meeting

Step 6: Mark Calendly Events as Conversions in GA4

If all events fired, congratulations! Your container is ready to be published. Based on the tag settings you imported, GA4 will begin populating the following events:

  • calendly_view
  • calendly_select_time
  • calendly_booking

If you would like to mark any of those events as a conversion (we recommend using only calendly_booking for conversion tracking), navigate to Configure > Events and use the toggle switches to enable Calendly events you’d like to set as conversions.

screenshot of ga4 events configuration settings

Other considerations

Our use case only involved one Calendly form embedded on a single contact page. In this situation, we know which Calendly widget is being used and what page it is on. For this reason, we set the label as {{referrer}} to see what pages are referring conversions. 

If you are using multiple Calendly event types on the same website you will need to adapt your implementation. 

  1. First, you will need to repeat steps two and three for each Calendly event to modify the embed code and create an event listener for each unique Calendly event. Be sure to match the Calendly event URL with the correct event.
  2. Rather than using {{referrer}} as the event label for each Event tag, make the label the name of your Calendly event. That way you will know which event was booked in Analytics. 

That’s it! If you run into trouble, send me an email at ben.hicks@ our domain.

Posted in GA4, Google Tag Manager