Form abandonment tracking with (and w/o) Google Tag Manager

A common requirement in measurement plans set by Marketing or Product teams is the ability to track form abandonment. With many of the teams mentioned above stressing over bringing in more and more leads, the ability to analyze and address where and why users drop off is important.

While there some tools that can measure a form’s conversion rate (e.g. Hubspot’s built feature) and even analyze specific fields (e.g. Hotjar Form Analysis tool), measuring this in Google Analytics can come in handy for in-depth analysis.

The output of measurement described below is this table of events in Google Analytics that can be used to analyze the drop-off points of users.

Form abandonment tracking in Google Analytics

Another classic use case of this data is creating Remarketing audience from these users that had expressed a clear interest in your product or service and only need that extra nudge. These can also serve as a great seed for and Lookalike audiences too.

Since this triggers a generic event, it can be used to create these audiences in any ad platform aside from Google Analytics/Ads, for example on Facebook Ads or Taboola.

Form abandonment tracking with Google Tag Manager

The simplest way I usually go about this is with Google Tag Manager (GTM). If you’re using GTM4WP, this is already baked in as an event (will appear in the Data Layer as gtm4wp.formElementEnter & gtm4wp.formElementLeave).

The method described below is based off of the Generic Event Tracking mechanism I’ve previously posted about. Using this generic tracking, adding additional event such as the form abandonment is a breeze.

Adding the Custom HTML tag

The first step to handling form abandonment is being able to identify to which point has a user gotten within a specific form. To achieve this we will use a simple jQuery script.

Important:
This assumes you already have jQuery active on your site (WordPress sites ship with it by default). If you don’t use jQuery, see the Vanilla JS solution below.

The purpose of this script is to capture a change in the value of a form field, and send the label of that field to GTM.

We will add this script as a Custom HTML tag in GTM. You can set the tag to trigger on any page or only on the pages where there are forms (e.g. only the Contact Us page).

<script>
jQuery("form input, form select, form textarea").change(function() {
    dataLayer.push({
        'event': 'form interaction',
        'form_field': jQuery(this).attr('placeholder')
    })
});
</script>

The output of this script will be an event sent to Google Analytics (using the Generic Event tag in GTM). The event’s name is ‘form interaction’ and the event’s parameter ‘form_field’ will record the field interacted with.

The Custom HTML Tag in GTM

In the example above, the field will be identified by its placeholder text. You can extract the field’s label attribute by replacing the placeholder value with label.

jQuery(this).attr('label')

Elementor forms

In Elementor forms, this value is also referenced as name or id. You can also grab the field’s label or the form’s name with a minor alteration:

'form_field_label': jQuery(this).parents('div').children('label').text(),
'form_field_id': jQuery(this).parents('form').attr('name')

You can also check out my guide on Bulletproof Elementor form tracking with GTM.

Contact Form 7 forms

In CF7 forms, this value is also referenced as id. You can also grab the field’s label or the form’s ID with a minor alteration:

'form_field_label': jQuery(this).parents('label').text(),
'form_field_id': jQuery(this).parents('.wpcf7').attr('id')

You can also check out my guide on Bulletproof Contact Form 7 tracking with GTM.

Gravity forms

In Gravity forms, this value is also referenced as name or id. You can also grab the field’s label with a minor alteration:

'form_field_label': jQuery(this).parents('li').children('label').text(),
'form_field_id': jQuery(this).parents('.gform_wrapper').attr('id')

Hubspot forms

In Hubspot forms, this value is also referenced as name. ou can also grab the field’s label with a minor alteration:

jQuery(this).parents('div').eq(1).children('label').text()

You can also check out my guide on Hubspot form tracking with (and w/o) Google Tag Manager.

Form abandonment tracking w/o Google Tag Manager

For those of you who don’t use GTM (shame on you!), there’s also a solution available. It utilizes the same jQuery and logic (see above for specific platforms) but triggers the event directly to Google Analytics via the gtag method.

Add this snippet to any page that has a form you want to track.

<script>
jQuery("form input, form select, form textarea").change(function() {
        gtag('event', 'form interaction', {
        'form_field': jQuery(this).attr('placeholder')
        });
});
</script>

You can also create a similar tracker for Facebook pixel events by altering the script (both GA and FB events can sit under a single script):

<script>
jQuery("form input, form select, form textarea").change(function() {
fbq('track', 'ViewContent', {
  content_name: jQuery(this).attr('placeholder')
 });
});
</script>

Vanilla JavaScript (w/o jQuery)

in case your site doesn’t use jQuery, you can still use a simpler version of this solution. Since JS lacks some of the methods that are trivial in jQuery (without complex setup), we can only grab the immediate value of the field’s name/label.

If you’re using Google Tag Manager, simply use this snippet. You can change the value of form to capture a specific form by class or id (e.g. .class or #id). You can also change the value of the attribute you’re

<script>
document.querySelector('form').addEventListener('change', function(e) {
    dataLayer.push({
        'event': 'form interaction',
        'form_field': e['target'].getAttribute('name')
    });
});
</script>

If you’re not using Google Tag Manager, you can use this snippet to trigger the event into Google Analytics.

<script>
document.querySelector('form').addEventListener('change', function(e) {
        gtag('event', 'form interaction', {
        'form_field': e['target'].getAttribute('name')
        });
});
</script>

Testing your selectors

If you want to test that you have the correct selectors, you can use this script. Simply paste it in your browser’s Console (click F-12 and navigate to the Console tab) and then interacting with any form on that page (the function resets on page navigation).

jQuery

jQuery("form input, form select, form textarea").change(function() {
        alert('The field value is '+jQuery(this).attr('placeholder'))
});

Vanilla JavaScript

document.querySelector('form').addEventListener('change', function(e) {
        alert('The field value is ' + e['target'].getAttribute('name'))
});

Caveats

While this approach is pretty simple, it does bring some challenges.

  1. This method doesn’t take into account the form’s ID. If you have one for per page, that’s no big deal (as GA events are tied to the page the user triggered them on). If you have multiple forms, e.g. a contact us form and newsletter footer , these can be difficult to analyze separately.
    In that case my suggestion is simply to add the form’s ID to the Event Label field (requires additional code, see above).
  2. Fields can be tracked multiple times – if a user edits a field multiple times, this will be recorded (not necessarily a bad thing)
  3. Browser autocomplete will trigger the fields impacted (again, not a bad thing)

5 Responses

  1. Hello Elad,

    You are really an Expert in your domain of analytics.

    I was looking for something like this to track the analytics for form abandonment tracking.

    Thanks a lot!!!

  2. Hello Elad,

    Thank you for your post on this subject. I am trying to get this to work for a WordPress site using Contact Form 7.

    I”ve implemented the code you provided into GTM.

    When I debug in GM, I can see the event, eventCategory and the eventLabel. Unfortunately the eventAction is blank. This is what I see:
    eventAction: ”,

    The following code you supplied seems like it should work:
    ‘eventAction’: jQuery(this).parents(‘label’).text(),

    When I look at the page source code this is the structure:
    YOUR NAME

    Any ideas?

    1. It depends if this is the field’s label or id.
      You can try instead this variation (for capturing the id instead of the label):
      ‘eventAction’: jQuery(this).parents(‘.wpcf7’).attr(‘id’)

      let me know if this helps

Leave a Reply

Your email address will not be published. Required fields are marked *

Related Posts