• GTM Courses
  • Blog
  • Services
  • Resources
    • View All Resources
    • GTM Recipes
    • GTM Community
  • About
    • About
    • Contact
  • GTM Courses
  • Blog
  • Services
  • Resources
    • View All Resources
    • GTM Recipes
    • GTM Community
  • About
    • About
    • Contact

August 24, 2018

Google Tag Manager Form Tracking: 7 Ways To Reach Your Goal

Updated: August 24th, 2018. While talking with marketers, I noticed that one of the most popular topics among them is form tracking. Unfortunately, in some cases form tracking might become a real pain in the butt (especially if a marketer has no clue what CSS or HTML is). But do not fear because in this blog post I’ll show you 7 Google Tag Manager form tracking techniques. Hint: some of them will require the developer’s input, but I’ll try my best to put everything in plain English.

 

Chapters of this blog post:

  • Google Tag Manager Form Tracking – Basic Context
  • Tag + Trigger
  • Which Google Tag Manager Form Tracking Method Should You Choose?
  • #1. Google Tag Manager Form Tracking With Form Auto-Event Listener
  • #2. “Thank You” Page Tracking With Google Tag Manager
  • #3. AJAX Form Tracking With Google Tag Manager
  • #4. Form Tracking with Element Visibility trigger
  • #5. Write Your Own Form Auto-Event Listener
  • #6. Google Tag Manager Form Tracking With Data Layer Events
  • #7. Form Tracking with help of DOM Scraping

 

Google Tag Manager Form Tracking: Basic Context

In this wonderful thing called THE INTERNET, there are various types of forms. Some of them refresh after a successful submission, some of them don’t, some of them might redirect you to a “thank you” page, etc. The main problem with form tracking is that there are no global standards of how forms must be developed. Some developers may prefer one technology (e.g. AJAX) over another – and they have a full right to do so.

Since you are interested in form tracking, you have probably noticed Form triggers and built-in Form variables in Google Tag Manager. Enable at least one form variable and create a Form Submission trigger (which listens to all form submissions), hereby you’ll turn on GTM’s Form auto-event listener.

google tag manager form tracking

Form auto-event listener listens for a standard submit browser event. However, a vast majority of forms use other ways to send their data (e.g. jQuery’s $.ajax) thus the submit event is prevented from working. In that case, Google Tag Manager never records a form submission. And that’s a pretty common problem.

If GTM’s form listener does not work in your situation, there are other alternatives for how you can reach the goal. In this blog post, I will explain both standard options and workarounds for Google Tag Manager form tracking.
Google Tag Manager Ebook Bundle

Tag + Trigger

You are probably already familiar with main Google Tag Manager concept: every interaction you want to track needs a tag and a trigger. If you want to track all form submissions with Google Analytics, you’ll need to create a Google Analytics Tag and a Trigger (rule) when a tag must fire. Creating a tag is the easy part of this process. Let’s make one – you’ll need it in next chapters of this blog post):

  1. Go to Tags
  2. Press New button
  3. In Tag Configuration choose Universal Analytics:
    1. Choose Track Type – Event
    2. Event Category – Form submission (feel free to choose another appropriate title)
    3. Event Action – Contact Form (feel free to choose another appropriate title)
    4. Event Label – {{Page URL}}. P.S. Feel free to choose other values for an event category, action and label.
    5. Select Google Analytics Settings Variable.
  4. Leave the Triggering part empty (for now) and click Save. We’ll get back to it later. 80% of this blog post is dedicated to various types of triggers you can make use of. The choice of trigger type depends on the way a form was developed.

Updated Google Analytics Tag - Form Submission

Those 7 form tracking techniques I mentioned in the title of this blog post are triggers. Each one of them depends on different elements/events that occur on a website after the form submission:

  • Form auto-event listener.
  • Thank you page.
  • AJAX form tracking.
  • Tracking with Element Visibility trigger
  • Writing your own form auto-event listener.
  • Datalayer event (dataLayer.push).
  • DOM scraping.

An incorrectly configured trigger will result in false data and reports (this will lead to wrong conclusions and actions). So read everything carefully. If you have any questions or if some parts of this blog post are misleading, let me know in the comment section below, Twitter or LinkedIn. I will be glad to help.

 

Before We Continue: Ready-made Guides

Now, before we dive deep into this guide, there’s something you should know. This entire guide is universal and covers pretty much every form on the planet (well, not maybe every, but around 95% (made-up statistics)).

However, to save you some time, I’d like to ask this: are you using Contact Form 7, Caldera Forms or Gravity Forms plugins?

If yes, then I have some good news for you. Here are three guides tailored to those popular form plugins:

  • How to track Contact Form 7 with Google Tag Manager
  • How to track Caldera Forms with Google Tag Manager
  • How to track Gravity Forms with Google Tag Manager

If your form is custom or built using another technology, don’t worry. I have covered all the tips in next chapters.

 

Which Form Tracking Method Should You Choose?

Before diving into the pool triggers, we’ll need to inspect a form and decide which technique fits our needs the best. I have prepared a flow scheme which should help you choose the right Google Tag Manager form tracking method. Google Tag Manager Form Tracking Flow

Open full scheme on a new window

 

I am sure that some parts of that scheme might look vague. Continue reading and everything will become much clearer.

 

#1. Google Tag Manager Form Tracking (with Form Listener)

First, let’s try GTM’s built-in form listener. Open a list of Variables in your GTM account. By default, form variables are disabled and hidden, therefore, you need to enable them. Under built-in variables, click Configure and in the right sidebar enable all Form variables (all changes are automatically saved).

google tag manager form variables

Then open a list of all your triggers (by clicking Triggers in the left sidebar). Create a new trigger:

  • Title “All form submissions”.
  • Trigger type – Form submission.
  • Leave Wait for tags unchecked.
  • Click Check validation checkbox. Once this is checked, GTM will not fire the Trigger if the default action of the form (submit and redirect) is prevented. If left unchecked, the Trigger will go off whenever a submit event is registered (even when a form is submitted with errors (e.g. several required fields are left blank)). In the screenshot below, I’ve enabled this trigger ONLY on the page where my contact form is located (Page Path contains contact-us)
  • Fire on. In this example, I set to track All forms (which are located in Contact Us page (because in the previous paragraph of this guide, I’ve set the trigger to be enabled only on a particular page).

Updated Form Tracking Trigger in Google Tag Manager

Now, let’s use GTM’s Preview and Debug mode to find out whether default form auto-event listener works for us. At the top-right corner of your Google Tag Manager account, click Preview.

Enable Google Tag Manager Debug Mode

Once the preview mode is enabled, you’ll see an orange banner looking like this:

Preview and Debug mode

It MUST appear. If the banner is missing, read this guide on how to fix GTM preview and Debug mode.

After Preview and Debug mode is enabled, navigate to the site where the form is and you will see a debug console at the bottom of your browser showing detailed information about your tags, including their firing status and what data is being processed. This console window will appear only on your computer as you preview the site, and is not visible to your other website visitors. It should look something like this:

preview and debug console

If you have already opened that page with the form but don’t see GTM’s debug console, refresh the page. If you still face problems, I suggest reading more about most common Google Tag Manager mistakes to find the solution.

Let’s get back to form tracking. Fill in the form (try not to leave any fields blank):

  1. Hit the submit button. Did a gtm.formSubmit event appear in the Preview and Debug console? If not, then GTM’s Form auto-event listener will not work with this form and you should choose next form tracking option described in this blog post.
    formSubmit event
  2. If gtm.formSubmit event did appear in Preview and debug console, then you should do another test – try leaving at least one required form field empty and submit the form again. This way you’ll imitate an error in your form:
    1. If gtm.formSubmit event fired once again, then you should check other form tracking options mentioned in this blog post.
    2. If gtm.formSubmit event did not fire – that’s great! It means that GTM will track only those form submissions which were successfully completed (and this is exactly what you need).

Great! We’ve identified that our form can be tracked with GTM’s built-in form listener. Let’s create a trigger specifically for that form. Remember gtm.formSubmit event that was previously mentioned? Click on it (in Preview and Debug mode), then click Variables.

Google Tag Manager form tracking

Then scroll down and start looking for any Form variable that is unique for that form. Usually, it will be Form ID variable, in other occasions – Form Classes (but Form ID is the best option (if possible)). As you can see in the image below, I have submitted a form (of which Form ID variable is form_contact2).

form submission variables

This is a good identifier that is not used on any other elements in the website, so I’ll use it for my trigger:

  1. Go to Triggers and click New
  2. Click Trigger configuration section and choose trigger type – Form submission
  3. Click Check validation and set the rule Page URL matches RegEx (.*). This rule means that this form submission trigger will be available on all pages. If you want to make it accessible only on particular pages, you can add more specific rules, such as Page URL contains /contact-us/ (it depends on URL of your contact form).
  4. Then configure this trigger to fire only on some forms and enter the following rule: Form ID equals form_contact2.
    1. If you don’t see Form ID variable – Enable it in the list of Built-in variables of Google Tag Manager.
    2. Form ID may (and probably will) be different in your situation (compared to my example).

Updated - Form Submit Trigger

 

Let’s Test

  1. Assign this new trigger to Google Analytics Tag that you created at the beginning of this blog post.
  2. Open (or refresh) a Preview and Debug mode, refresh a web page with a form you want to track.
  3. Then fill in the form and submit – if Google Analytics Tag fired, that’s good news! Also (if possible), try submitting a different form on your website: in case of successful submission, a GA tag should not fire.

 

 

#2. “Thank you” Page Tracking with Google Tag Manager

If standard form listener in Google Tag Manager does not work in your case, you should check whether that form redirects a user after a successful submission to another page.

  • If yes, what URL (web address) does it redirect to?
    form success URL

    • Is that address unique?
    • If yes, can users just navigate to that page without actually submitting a form? If the answer to the last question is no, then you can create a pageview trigger which fires only on that success page. Tip: you can always check your Google Analytics Behavior flow reports to see whether users access success page from different locations of your website. Your goal here is to avoid accidental visits of success (a.k.a. “Thank you” page) as much as possible.

Now let’s create a trigger which fires only on success page.

  1. Go to Triggers in Google Tag Manager
  2. Press New button
  3. Choose trigger type – Pageview and Some page views
  4. If the visitor is redirected to https://www.example.com/form/thankyou.html, then you can set one of the following rules for this trigger:
    1. Page Path equals /form/thankyou.html.
    2. or Page URL contains /form/thankyou.html. Try being as specific as possible. Setting just “thankyou” as the rule for this trigger might not be the best idea because there might be other pages, that can contain that word (and we don’t want that!) in URL.
  5. And do not forget to properly name the trigger – “Pageview – Successful Form Submission”. A title must be clear, otherwise, you’ll have a mess in your GTM account (in the long run). You can read more about naming tips (a.k.a. Naming Convention) here

Google tag manager form tracking - pageview success page

 

Let’s Test

  1. Assign this new trigger to Google Analytics Tag that you created in the beginning of this blog post.
  2. Open (or refresh) a Preview and Debug mode, refresh a web page with a form you want to track.
  3. Then fill in the form and submit. After successful submission, you’ll be redirected to a “Thank you” page – if Google Analytics Tag fired, good job! Also (if possible), try submitting a different form on your website (to see if the tag did not fire on accident).

Subscribe and Get the Ebook - Real Book Img - GTM for Beginners

#3. AJAX Form Tracking with Google Tag Manager

If you are reading this part, your form is probably not sending valid form submit events and is not redirecting users to a “thank you” page. It probably just refreshes itself and then displays “You have successfully filled in the form” message without the actual page refresh. There’s a big chance that this form is using AJAX. I suggest skipping all the technical mumbo-jumbo here (since I am not a developer + I don’t think I am capable of clearly explaining how it works). The only thing here you should know is AJAX listener.

Lunametrics have shared an awesome AJAX listener for GTM everyone can use for free. If you want to read more about how it works, you can do that on Lunametrics blog. Here we’ll borrow their code to track form submissions. Copy the code below and paste it in the Custom HTML tag on GTM:

JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
<script id="gtm-jq-ajax-listen" type="text/javascript">
(function() {
 
'use strict';
var $;
var n = 0;
init();
 
function init(n) {
 
// Ensure jQuery is available before anything
if (typeof jQuery !== 'undefined') {
// Define our $ shortcut locally
$ = jQuery;
bindToAjax();
 
// Check for up to 10 seconds
} else if (n < 20) {
n++;
setTimeout(init, 500);
 
}
 
}
 
function bindToAjax() {
 
$(document).bind('ajaxComplete', function(evt, jqXhr, opts) {
 
// Create a fake a element for magically simple URL parsing
var fullUrl = document.createElement('a');
fullUrl.href = opts.url;
 
// IE9+ strips the leading slash from a.pathname because who wants to get home on time Friday anyways
var pathname = fullUrl.pathname[0] === '/' ? fullUrl.pathname : '/' + fullUrl.pathname;
// Manually remove the leading question mark, if there is one
var queryString = fullUrl.search[0] === '?' ? fullUrl.search.slice(1) : fullUrl.search;
// Turn our params and headers into objects for easier reference
var queryParameters = objMap(queryString, '&', '=', true);
var headers = objMap(jqXhr.getAllResponseHeaders(), '\n', ':');
 
// Blindly push to the dataLayer because this fires within GTM
dataLayer.push({
'event': 'ajaxComplete',
'attributes': {
// Return empty strings to prevent accidental inheritance of old data
'type': opts.type || '',
'url': fullUrl.href || '',
'queryParameters': queryParameters,
'pathname': pathname || '',
'hostname': fullUrl.hostname || '',
'protocol': fullUrl.protocol || '',
'fragment': fullUrl.hash || '',
'statusCode': jqXhr.status || '',
'statusText': jqXhr.statusText || '',
'headers': headers,
'timestamp': evt.timeStamp || '',
'contentType': opts.contentType || '',
// Defer to jQuery's handling of the response
'response': (jqXhr.responseJSON || jqXhr.responseXML || jqXhr.responseText || '')
}
});
 
});
 
}
 
function objMap(data, delim, spl, decode) {
 
var obj = {};
 
// If one of our parameters is missing, return an empty object
if (!data || !delim || !spl) {
 
return {};
 
}
 
var arr = data.split(delim);
var i;
 
if (arr) {
 
for (i = 0; i < arr.length; i++) {
 
// If the decode flag is present, URL decode the set
var item = decode ? decodeURIComponent(arr[i]) : arr[i];
var pair = item.split(spl);
 
var key = trim_(pair[0]);
var value = trim_(pair[1]);
 
if (key && value) {
 
obj[key] = value;
 
}
 
}
 
}
 
return obj;
 
}
 
// Basic .trim() polyfill
function trim_(str) {
 
if (str) {
 
return str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, '');
 
}
 
}
 
 
})();
/*
* v0.1.0
* Created by the Google Analytics consultants at http://www.lunametrics.com
* Written by @notdanwilkerson
* Documentation: http://www.lunametrics.com/blog/2015/08/27/ajax-event-listener-google-tag-manager/
* Licensed under the Creative Commons 4.0 Attribution Public License
*/
</script>

Set that Custom HTML tag to fire on all pages. Now, let’s check whether a form is built on AJAX:

  1. Enable (or refresh) Preview and Debug mode.
  2. Refresh the web page with a form.
  3. Try submitting the form (with no errors).
  4. Did the ajaxComplete event appear in the Preview and debug console?
    1. If yes, the form is using AJAX.
    2. If no, skip to the next chapter of this blog post.

If your answer to the previous questions was Yes, let’s take a look at what can we do with that AJAX form. Click ajaxComplete event in Preview and Debug mode, then click Data Layer:

ajax complete

Looks difficult for a non-developer, right? But it’s easier than you think. This is the data that was passed to data layer after successful submission of the form, each line is a separate dataLayer data point which can be used as dataLayer variable in GTM. You should be looking for something which helps identify successful form submission. Scroll down and look for “response”.

 

ajax form response

Let’s take a closer look at it. Can you see a message “This message has been successfully sent”? Bingo! We can use it as a trigger.

First, let’s create a Data Layer variable in Google Tag Manager.

  1. Go to Variables
  2. Scroll down to User-Defined  variable and hit New
  3. Click Variable configuration and choose variable type – Data Layer Variable
  4. Enter Data Layer Variable Name – attributes.response. Leave all other settings as they are.
  5. My recommendation for Title of this GTM variable is dlv – attributes.response (“dlv” stands for Data Layer Variable).

Data Layer variable - attributes.response

You’re probably guessing why I entered attributes.response as Data Layer Variable Name, instead of just response. Let’s take a closer look at Data Layer in Preview and Debug mode. In line 2 you see event name ajaxComplete – that’s the same name which appears in Preview and Debug console’s left side. Then we see attributes which is an object containing various data points (key-value pairs). And the response is one of those keys.

ajaxComplete - full response

So when we want to tell Google Tag Manager that we are interested in response’s value, we need to tell the exact path to that data. In our case, it’s attributes → response. Each level of the path must be separated with dot → attributes.response . Another example: let’s say you’re interested in Server data (from that very exact AJAX response). In that case, Data Layer Variable’s Name should be attributes.headers.Server  .

After we created an attributes.response Data Layer variable in Google Tag Manager, let’s debug. Refresh Preview and Debug mode and refresh the page where the AJAX form is. For educational/testing purposes, I’m using forms from this website (use Example 1). Feel free to try them by yourself.

Fill in the form and submit. Click the most recent ajaxComplete event in Preview and Debug console, then navigate to Variables tab and find the new variable dlv – attributes.response. If you did everything correctly, it should look like this:

attributes.response dlv

That’s a message of successfully submitted form. If the value of that variable is undefined, then you should start looking for mistakes. Most common ones are typos in the variable name or inaccurately defined variable’s path. Some guys just try using response instead of attributes.response. 

Now let’s create a trigger which fires when the event is ajaxComplete AND our new Data Layer variable contains text The message has been successfully sent.

  1. Go to Triggers and click New
  2. Choose Trigger Type – Custom Event. If you’re new to this, Custom event = Data Layer event. Lunametrics’ AJAX listener creates a Data Layer event (via dataLayer.push method) each time an AJAX request is made.
  3. Enter Event name – ajaxComplete
  4. This trigger should fire on Some Custom Events.
  5. Define a condition when the trigger will fire – dlv – attributes.response contains The message has been successfully sent.

Custom Trigger - Ajax Complete Form Submission

 

Let’s Test

  1. Assign this new trigger to Google Analytics Tag that you created at the beginning of this blog post.
  2. Open (or refresh) a Preview and Debug mode, refresh a web page with a form you want to track.
  3. Then fill in the AJAX form and submit. After successful submission, Google Analytics Tag should fire (it will be displayed in Preview and Debug mode. You can also check Google Analytics Real-time event reports).

Things to keep in mind when tracking AJAX forms:

  1. The response of your form might look different so try adjusting my tutorial to your situation.
  2. If developers change the response’s data, your trigger will fail. Inform developers about your GTM implementation.
  3. If the page contains more than one AJAX form, try looking for more information in Data Layer which can help Google Tag Manager tell the difference between those forms.
Google Tag Manager Ebook Bundle

 

#4. Track Forms with Element Visibility Trigger

One of the most awesome triggers in GTM (in my opinion) is the Element Visibility trigger. It enables you to track when a particular element appears on the screen (due to scrolling or some other circumstances).

The same technique can be applied to forms when a particular message (e.g. “Thank you”)  appears after a form is successfully submitted.

The first thing we need to do here is to inspect the success message of a form. We’ll need to find a way how to instruct Google Tag Manager which particular website element are we interested in.

After you submit the form successfully, right-click on the success message and choose Inspect Element.

Inspect Element - Form Success Message

You will then see browser’s developer tools that contain various information about the message: its content, CSS class, etc. In the example below I see that the message has a class “thanks” which could be used as a condition in the Element Visibility trigger. It was even better if the success message had a parameter called “id” but since it’s not available, we’ll use CSS class.

Thank you message of a form

Let’s go to your Google Tag Manager container and go to Triggers. Create a new trigger and choose Element Visibility as its type. The key ingredient here is the Selection Method that will help GTM understand what we are looking for.

selection method

Selection method has two options: Element ID and CSS Selector. Since the success message in my example has no id (but “class”, we’ll go with CSS Selector.

In the Element Selector field, we need to paste that class “thanks”. In CSS, every class is defined with a dot in front of it, so let’s do the same.

Finally, make sure you tick “Observe DOM changes”. This setting means that if an element appears on the screen not due to scrolling but under some other circumstances (e.g. “just simply pops in”), GTM will catch it (most likely).

Take a look at the screenshot below. If you want, you may do some other tweaks but what I did was a bare minimum.

Element Visibility Trigger in form tracking

Save the trigger.

 

Let’s Test

  1. Assign this new trigger to Google Analytics Tag that you created at the beginning of this blog post.
  2. Open (or refresh) a Preview and Debug mode, refresh a web page with a form you want to track.
  3. Then fill in the form and submit. After successful submission, in P&D console you will see gtm.elementVisibility event. Click it and you will see that GA tag has fired. If you don’t see the gtm.elementVisibility event, you probably made some mistake in the Selection method or CSS selector field. Or forgot to enable Observe DOM changes checkbox.

If your success message has no ID or proper CSS class, you’ll need to dive deeper into CSS selectors because their possibilities are enormously huge.

 

 

#5. Write Your Own Form Auto-Event Listener

Yes, I know that this sounds complicated. Actually, this can’t be further from the truth. In one of my blog posts, I’ve explained how you can write an auto-event listener with no coding skills. You should definitely check it out.

Auto-event listeners are these super useful JavaScript functions which track particular interactions on a web page. In case something noteworthy occurs, they fire Data Layer events which can be used as triggers in GTM. Furthermore, those events contain valuable data which can be transferred to other tools, like Google Analytics, Adwords, Mixpanel, you name it.

By default, Google Tag Manager offers a built-in Form Auto-Event Listener, but as you already know, its support is pretty poor (otherwise, this blog post wouldn’t exist).

Anyway, in the aforementioned blog post, I’ve explained 7 steps how you can validate the idea and create an auto-event listener. And for sake of clarity, I’ll illustrate with the actual example.

Before we continue, check what kind of form are you using. Is it custom made and created exclusively for you? If yes, skip to the Chapter #6 of this blog post. Otherwise, continue reading.

If your website is running on WordPress, then you definitely are using some sort of form plugin. Find out its name/brand/title/etc. Found it? Great. Let me take you through the 7-step-process of writing your own form auto-event listener without coding skills.

As an example, I’ve chosen Gravity Forms, a WordPress Plugin.

 

STEP 1. Check if There Are Any Ready-made Solutions

First of all, you need to check whether there is a ready-made Gravity Forms GTM listener somewhere on the web. Last time I checked it, there was none. Although you might say Hey, I’ve googled “Gravity Forms Google Tag Manager” and there ARE some tutorials, all I can say is that they aren’t as good as you might think.

I tried to track Gravity Form once. The problem was that the form dispatched a form submission event even if the form was submitted empty (with no fields filled in!). And those blog posts did not help me to solve this issue, so I had to find a way around.

That’s where this GTM Form Tracking Method #4 became really useful. Continue reading.

 

STEP 2. Let’s Check Whether There is a JavaScript API

Open Google and enter Gravity Forms Javascript API. It’s crucial that you look for JavaScript API, not regular API. Your search results should look like this:

Gravity Forms JavaScript API

The 2nd search result looks promising. Let’s click it. We should be one step closer to writing an auto-event listener.

 

 

STEP 3. Let’s See Which JS API Methods Are Available

Now, check whether the API is well documented and easy-to-understand even for those who do not know how to code. Since we want to track ONLY successful form submissions we should keep looking for some terms which contain “success”, “form submission”, “confirmation”, etc. You get the idea right?

What we are looking for is some kind of API method which is related to successful submissions. Honestly, it took me a while to find a proper page in Gravity Form’s documentation (because they offer A LOT of stuff).

On the left side of the Gravity Forms API reference, you’ll find a navigation bar. Go to Hooks > Filters > Confirmations > gform_confirmation_loaded. This JavaScript hook (gform_confirmation_loaded) fires when the form’s “Success” page is loaded (which is exactly what we’re looking for!).

Gravity Forms Confirmation Loaded API Reference

Bingo! We’re one step closer to success but there’s still something we need to verify.

 

STEP 4. Are Code Examples Ready-to-use and Very Simple?

Even if the API offers useful methods and the documentation is very well written, there’s still one requirement left. Is the API Reference really dummy-proof? Will a non-developer be able to use it with ease?

Honestly, it is not a very common practice to write super simple code examples in API references which could be useful for non-devs or beginners. Sometimes it’s even next to impossible.

For example, Wistia offers a very well-written Javascript API reference, but examples are not designed for entry-level developers, thus you and I won’t able to write our own custom auto-event listeners.

In Wistia’s case, we’re lucky to have Lunametrics because their developers posted this awesome Wistia listener for GTM. But there are still lots of situations where a ready-made tracking solution just simply does not exist.

OK, let’s go back to Gravity Forms. I have navigated to gform_confirmation_loaded JavaScript hook and found this example of code:

gform_confirmation_loaded javascript snippet

This is perfect! Let me explain what’s happening.

This code is ready to use. It states: if gform_confirmation_loaded occurs, initiate a function. Currently, that function is empty but we can easily embed the dataLayer.push event just by replacing the text //code to be trigger when the confirmation page is loaded with the actual data layer code.

 

STEP 5. Add dataLayer.push Event(s)

Copy that code from Gravity Forms API documentation and paste to some plain text or code editor (e.g. Notepad, Notepad++, Sublime, etc.)

JavaScript
1
2
3
4
5
<script type="text/javascript">
jQuery(document).bind('gform_confirmation_loaded', function(event, formId){
// code to be trigger when confirmation page is loaded
});
</script>

Remove //code to be trigger when the confirmation page is loaded

JavaScript
1
2
3
4
5
<script type="text/javascript">
jQuery(document).bind('gform_confirmation_loaded', function(event, formId){
 
});
</script>

Prepare dataLayer.push event code (various GTM experts recommend to use window.dataLayer.push instead of plain dataLayer.push):

JavaScript
1
2
3
4
5
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
'event': 'formSubmission', //you can actually name this even whatever you want
'formID': formId
});

Why did I add “formId”? Well, that’s because the Gravity Form’s JavaScript webhook returns the ID of the form (see function(event, formId) ?). It’s optional, so feel free to remove it.

Now, merge the Gravity Form’s code snippet with window.dataLayer.push. This is what the final result should look like:

JavaScript
1
2
3
4
5
6
7
8
9
10
11
<script type="text/javascript">
jQuery(document).ready(function() {
   jQuery(document).bind("gform_confirmation_loaded", function(event, formID) {
     window.dataLayer = window.dataLayer || [];
     window.dataLayer.push({
       event: "formSubmission",
       formID: formID
     });
   });
});
</script>

Great! We’re very close to finishing the Gravity Form auto-event listener!

 

STEP 6. Create a Custom HTML Tag and Test

In Google Tag Manager account, create a new Custom HTML tag. Paste the code you have created in the previous step.

Gravity Forms Listener

Done! Save the tag and assign the trigger you want, e.g. All Pages (or just on those pages where the form is located).

Don’t forget to test the listener with GTM Preview and Debug mode. Load the page with any Gravity Form and complete a test submission. A Data Layer event called formSubmission should appear in the event stream. Click it and check what data was passed to the Data Layer. It should look like this.

Form Submission Data Layer Event

 

STEP 7. Success

If everything worked as I have described, create Data Layer variable formId (learn how to access data in the Data Layer) and create a Custom Event Trigger formSubmission. Use this variable and trigger in your Universal Analytics or any other tag.

Congratulations! You have written your first GTM Auto-Event Listener. If this Google Tag Manager Form Tracking method didn’t work, continue reading and maybe you’ll what you’re looking for.

Google Tag Manager Ebook Bundle

#6. Form Tracking with dataLayer Events

Disclaimer: Although this form tracking method is equally robust solution compared to standard GTM’s Form Listener (see Technique No. 1), I placed it as a No.6 option in this list for a reason.

When other marketers approach me for form tracking advice, they’re looking forward to a solution when developer’s input can be avoided. “Manage your marketing tags without help from developers” is one the main reasons why they start considering Google Tag Manager in the first place. This statement was among GTM’s key “selling” points when it was launched, so it’s no surprise marketers are expecting this to be 100% true. Although we know that in a lot of situations developer’s help is strongly advised. My position here:

  1. If you have access to developers and Google Tag Manager’s Form listener isn’t working for you, I recommend using dataLayer.push method which I will describe further.
  2. If you don’t have access to developers or they are super busy (and they probably are), then it’s okay to track with other techniques mentioned in this blog post. Just be aware, that other solutions have a bigger chance to break when developers make constant updates to a website you’re tracking. This especially applies to technique No. 7 – DOM scraping.

I hope I made my point clear and we can continue.

As it was mentioned above, if standard Google Tag Manager Form listener does not work with your form, the next best thing is to ask the developer to implement a custom dataLayer.push() into the callback function which is invoked upon a successful form submission. The piece of code could be something like:

JavaScript
1
2
3
4
5
6
window.dataLayer = window.dataLayer || [];
  window.dataLayer.push({
   'event': 'formSubmission',
   'formType': 'Contact us',
   'formPosition': 'Footer'
});

You’ll need to prepare a short but well-written and clear task for a developer:

  1. First, choose a name for the event. In the example above I chose formSubmission.
  2. Then think of any additional data you may need. Write those data points down and try categorizing them.
    1. In my imaginary website, I have several types of forms – “Contact us” and “Newsletter Subscription”. So I decided to have a dataLayer variable formType.
    2. Another useful parameter (in my opinion) is form position, because some forms are in the footer, and others are in the sidebar of a website. Why not make it another dataLayer variable?
  3. If a developer is new to dataLayer events and Google Tag Manager in general, hand them a link to this dataLayer.push guide with clear examples. Explain to them that you need an event with additional variables pushed into dataLayer after the successful form submission. If developers still have questions, this blog post should enlighten them.

Done! After the developer implements dataLayer.push in all forms, you should test it:

  1. Open Preview and Debug mode.
  2. Refresh the page with the form.
  3. Try submitting the form:
    1. Leave at least one required field blank. In this ca, e dataLayer event must not be pushed.
    2. Fill in all fields and try submitting again. Did the event appear in Preview and debug console? It should look like this:
      formSubmission event
    3. Check whether all data is correctly pushed to dataLayer. Click formSubmission event and then open Data Layer tab in Preview console. Data should look like this:
      formSubmission dataLayer

Setup variables and triggers in GTM. In my dataLayer.push example, there are two data points I’d like to use as variables – formType and formPosition, so I need to include them to Google Tag Manager by creating Data Layer variables.

1st variable:
Title:
dlv – formType
Variable type: Data Layer Variable
Data Layer Variable Name: formType
Leave all other settings as they are

2nd variable:
Title:
dlv – formPosition
Variable type: Data Layer Variable
Data Layer Variable Name: formPosition
Leave all other settings as they are

Now, let’s create a trigger. Go to Triggers and click New. Enter the following settings:

Trigger Type: Custom event
Event name: formSubmission (it may differ depending on your situation. Just make sure you and your developer are using the same name).
This trigger fires on: All custom events. This means that all formSubmission events will be tracked.

 

Let’s test

  1. Assign this new trigger to Google Analytics Tag that you created in the beginning of this blog post.
  2. Open (or refresh) a Preview and Debug mode, refresh a web page with a form you want to track.
  3. Then fill in the form and submit. After successful submission, Google Analytics Tag should fire (it will be displayed in Preview and Debug mode. You can also check Google Analytics Real-time event reports).

Tip: In this example, I’d recommend making a few changes to Google Analytics Event Tag. In the beginning of this blog post, I suggested creating a GA event tag with the following values:

  • Form submission as Event Category
  • Contact form as Event Action
  • {{Page URL}} as Event Label.

Updated Google Analytics Tag - Form Submission

Since we asked our developer to add few additional variables via dataLayer.push, we can utilize this data and push it to GA. We could change:

  • Event Category – from Form submission to Form submission: {{formType}}
  • Event Action – from Contact form to {{formPosition}}
  • Leave Event Label as {{Page URL}}

How will this event be displayed in Google Analytics event reports? Let’s say a visitor subscribed to our newsletter. The values pushed with Google Analytics Event will be:

  • Event Category: Form submission: Newsletter Subscription
  • Event Action: Footer
  • Event Label: https://www.analyticsmania.com/mega-blog-post/

 

 

#7. Form Tracking with DOM Scraping

This method should never be your first option. Try using the aforementioned 6 Google Tag Manager Form tracking methods before you continue reading this chapter.

If developers often update the website’s code, you should treat DOM scraping as the last resort due to its riskiness. It’s better than “no form tracking at all”, but it’s less robust than other options described in this blog post.

Although you gain a lot of flexibility and agility, it hardly depends on the website front-end’s structure. Even a slight change committed by developer might break your implementation. Also, it requires some knowledge of Javascript and DOM concepts (which is not a very common skill among marketers).

For this example, we’ll be using DOM Element Variable. It is a variable in Google Tag Manager which lets you scrape content directly from Document Object Model (in other words: with its help you can transfer any text on your website into a Variable and pass it on to your Marketing tools (e.g. Google Analytics)).

Now let’s open a demo Shopify store Brooklyn Theme and see everything in action. I’d like to apologize Shopify folks in advance for spamming their demo website with fake email submissions (but I’m sure they’re fine with it). There is a Signup up to our mailing list form at the bottom of their homepage.

email form
Quick off-topic note: If you haven’t, consider subscribing to my monthly email newsletter for more useful Google Tag Manager guides

Enter [email protected] in that Shopify form and hit Subscribe. A page will refresh, the web address will change to https://brooklyn-theme.myshopify.com/?customer_posted=true#contact_form, and that little form displays a “Thank you” message.
thank you for subscribing

In this case, we could easily track form submissions with Pageview trigger of Thank you page, but let’s imagine that page’s address (URL) did not change. This is not a common situation, but it’s possible. That’s where DOM Element Variable might come in handy. We could create a trigger which could scan a website and look for a success message “Thanks for subscribing”.

First, let’s create a DOM element variable looking for that particular success message. Hover your mouse cursor over success message’s text, click right mouse button and choose Inspect.

Right click - Inspect Element

A developer’s console will appear with a lot of HTML code. Note that success message’s code is already selected in that console. That message does not have any unique ID so we’ll need to utilize CSS Selectors.

Inspect element

At the bottom of the screenshot, you can see a line of CSS selectors, e.g. div.note.form-success. These selectors can help us identify the exact element of the website.

Let’s create a DOM Element variable and try to scrape “Thanks for subscribing” text.

  1. Go to Variables
  2. Scroll down to user-defined variables and click New
  3. Choose Variable type – DOM Element Variable
  4. Selection method – CSS selector
  5. In Element selector field enter div.note.form-success
    CSS selectors - short
    See what I did there? I entered the last CSS selector from the screenshot above. I also verified CSS selector according to Measureschool’s DOM scraping tutorial (start from 3:12), because there’s a possibility of more website elements with similar CSS selector. I want to track only that particular success message, so I need to make sure my CSS selector is unique.
  6. In case there were more than one possible success messages on a website with similar CSS selector, I would have used a longer CSS selector, for example, “#contact_form div div.note.form-success” (without quotation marks)
    css selectors
  7. Leave Attribute name empty.
  8. Variable’s title could be DOM – Form Success Message.
  9. Hit Save.

 

Let’s test

  1. Enable Preview and Debug mode (or refresh if it’s already launched).
  2. Refresh the page with form (or delete ?customer_posted=true#contact_form in URL) and try submitting it.
  3. Choose Page view event in Preview and Debug console and click Variables.
    DOM variable in PD console
  4. If DOM – Form Success Message variable’s value is Thanks for subscribing, you did a good job.

Alright! Now we need to create a trigger which depends on our new DOM variable.

  1. Go to Triggers and click New
  2. Choose Trigger type – Pageview
  3. This trigger fires on: Some Pages
  4. Enter the following condition: DOM – Form Success Message equals Thanks for subscribing. This means that the trigger will fire only on those pages where Form success message is displayed to visitors.

 

Do not forget to test:

  1. Assign this new trigger to Google Analytics Tag that you created in the beginning of this blog post.
  2. Open a Preview and Debug mode (or refresh), reload a web page with a form you want to track.
  3. Fill in the form and submit. After successful submission, Google Analytics Tag should fire (it will be displayed in Preview and Debug mode. You can also check Google Analytics Real-time event reports).
  4. Also, try submitting a form with an intentional error and see whether the tag fires (spoiler alert: it shouldn’t).

 

Final word

In this blog post, I described seven form tracking methods with Google Tag Manager. This has been the largest guide on this blog so far and I hope you found it useful. You should now be able to track much more forms without a developer’s input. But remember – it’s okay to ask for the developer’s help. If possible, choose dataLayer.push method over DOM scraping. Robust solutions should be your priority.

Did I skip something in this post? Is there some aspect of form tracking that you’d want more information on? Drop me a comment, and let’s see what we can come up with!

 

 

Julius Fedorovicius
In Form Tracking Google Tag Manager Tips
183 COMMENTS
Alex Orozco
  • Feb 2 2017
  • Reply

This is the most accurate post I've read about this theme. Thank you Julius, just wrapping my head on Google Tag Manager here and it seems like a debris at first but I hope this does make easier the event tracking.

I was a little bit confused over the Check validation stuff, I'll be testing this during these days to see if it works (found a bug on the form but I don't think is a big deal, I'll fix it)

This post goes to my favorites!

Julius Fedorovicius
  • Feb 3 2017
  • Reply

Working with GTM becomes easier with more time, you just need to break the ice.

And thank you for such a positive feedback! Consider subscribing to my newsletter for future updates on GTM topic.

Omaira Rodriguez
  • Mar 15 2017
  • Reply

I love it! I've been struggling to track a form through GTM for about 2 days until I landed this amazing article! Your writing is awesome and makes everything looks easier. Thank you so much!

    Julius Fedorovicius
    • Mar 16 2017
    • Reply

    Thanks for such a positive feedback!

Tammy
  • Apr 12 2017
  • Reply

Thanks very much for your article! Very helpful!

Julius Fedorovicius
  • Apr 12 2017
  • Reply

You're welcome. Consider subscribing to my newsletter for more GTM tips https://forms.soundest.net/signup/v1/57d65dd940a0fb313b554284.html

Erdem
  • May 17 2017
  • Reply

This is really great post including many topics about GTM besides form tracking.

Dominykas
  • Jun 7 2017
  • Reply

I am trying to track one AJAX form that has dlv - attribute.response variable and its return type is an object rather than a string. Thus, I am unable to make a trigger using contains/equals choices. Is there any way around this?

    Julius Fedorovicius
    • Jun 7 2017
    • Reply

    Hey, is that form publicly accessible? Drop me a link. I'd like to take a peek at it and see what we can do.

    Funmi
    • Jun 16 2017
    • Reply

    Hi, I'm having the same issue

      Funmi
      • Jun 16 2017
      • Reply

      Wrong email address above

        Julius Fedorovicius
        • Jun 16 2017
        • Reply

        Can I see the form which you want to track?

          Michiel
          • Jul 13 2017

          I have the same issue. The form is located on https://www.demeeuw.com/contact/contactformulier/
          Can you help out?

          Julius Fedorovicius
          • Jul 13 2017

          Hi,
          You need to go one level deeper and create a Data Layer variable with value "attributes.response.Message" (without quotation marks)

          Then create a Custom trigger with the following settings:
          - Event Name ajaxComplete
          - Some Custom events
          - attributes.response.Message variable CONTAINS Je gegevens zijn succesvol verzonden

          As long as the Success message text does not change, your form tracking should be fine.

          K
          • Apr 21 2019

          Hey Julius.. this tutorial and website is amazing.. thanks so much. I had been struggling with this for a few weeks but the list is a great protocol to work through.. and the AJAX one half works.. It managed to trigger the tag, but it triggers even if the form was not not submitted successfully (i.e. incorrect email address or other error).. there seems to be an issue with the trigger not reading the variable correctly. The form is here - https://www.maxautolease.com/ ...if you can offer any insight i would greatly appreciate it. Thanks!

clayton
  • Jun 20 2017
  • Reply

Great post thanks Julius! A client of mine had form submissions tracking correctly via the first method (fire tag on any/all gtm.formSubmit) but then all of a sudden on May 22 a blank gtm.formSubmit was happening to facebook.com/tr... upon pageload.

I was able to fix the trigger by adding a condition based on the class of the form when submitted correctly but I'm curious if you happen to know of anything recent changes to GTM that could have caused this?

The site is wordpress, with form plugins and I believe the facebook.com/tr form submit event is from the Facebook Pixel. It's just so strange that the issue popped up all of a sudden with no changes to the GTM confirguration - leading me to think there was an update to how GTM works, wordpress, the form plugin, or the facebook pixel.

Thanks and no worries if this is too specific to troubleshoot.

Stefano
  • Jun 26 2017
  • Reply

Hi Julius,
really great post!
Do you have any suggest to track an ajax form inside an iframe?

Thanks a lot

Stefano

    Julius Fedorovicius
    • Jun 26 2017
    • Reply

    Hi, sorry. To be honest, I have never tried to track Ajax in iframe. But I guess I'll need to run this experiment in the future.

LauraB
  • Jun 27 2017
  • Reply

BOOKMARKED!!! Thanks so much for this really helpful article! I have endless fun/nightmares with forms so this will be used often, if flow charts could be awesome - yours it pretty close to that title. Thanks again :)

Roberto
  • Jul 12 2017
  • Reply

Hello, I want to know when a user live the signup process but if they field or not the input, don't want to know the information only true or false if they field that form or not to know how to improve

How can I ask for these variables with know the data in analytics?

regards, Roberto.

    Julius Fedorovicius
    • Jul 13 2017
    • Reply

    Hi, The most robust solution would be to ask a developer to fire a data layer event when the form is submitted. That event could contain data which fields were filled in.

    I am not good at writing my own JavaScript, so I cannot assist you with Custom Javascript variables here. Well, at least not for now.

An Le
  • Jul 18 2017
  • Reply

Hi, thank you so much for your post. It is very helpful for me
But i have some problem. when i choose Some Custom Event with dlv attributes.response contains "Success Fully Sent..", but i not works. when i choose all custom event, it works.
Thank in advance!
An Le

    Julius Fedorovicius
    • Jul 18 2017
    • Reply

    Hey, could you share a link with me to that form? Obviously, there's an issue with your trigger condition but I need to see the form in action.

      An Le
      • Jul 18 2017
      • Reply

      Hi!
      This is the site "http://studinter.vn/lien-he-2/"
      there are two form with angularjs ajax
      Thank you so much
      An Le

        Julius Fedorovicius
        • Jul 18 2017
        • Reply

        Here's a solution.
        1. Create a dataLayer variable with the following value: attributes.response.message (this is case sensitive so make sure all letters are lowercase)
        2. Create a trigger with the following settings:
        -- Type: Custom
        -- Event name: ajaxComplete
        -- Condition: attributes.response.message CONTAINS "Success Fully Sent" (without quotation marks). This is also case sensitive, so make sure that every word starts with an uppercase letter.

        By the way, I noticed that after successful form submission two identical ajaxComplete events fire. In order to avoid duplicate events in Google Analytics, make sure to fire GA tag "Once per page". You can find Tag Firing Option under Advanced settings of Google Analytics Tag.

        Good luck!

          An Le
          • Jul 18 2017

          Hi,
          Thank you so much, it works
          I have set once per page just now.
          Again, Thank you so much!
          An Le

Jesus
  • Aug 3 2017
  • Reply

Hi,
Not sure if your post will work for Ajax Forms.
I am using NinjaForms and the form shows a confirmation message in the same page.
You can check a test page here https://www.thefrenchcandle.com/contact
I would like to be able scrap when this confirmation message is showed but I haven't been able. I tried but the variable doens't populate on the pageview tag as the pageview tag has not this information when it's fired.
Thank you in advance,
Jesus

    Julius Fedorovicius
    • Aug 3 2017
    • Reply

    Hi, my post works with AJAX forms (I've already used it multiple times). However, there's something strange with your form. Whenever I submit it and go to Preview and Debug console's Data Layer tab, my browser just crashes and I cannot do anything about it.

    I believe you should consult with a developer about this unusual behavior.

Joo
  • Aug 8 2017
  • Reply

Hi,
Thanks for the great post!

I just wonder how I track all form input values.

Thanks in advance.

    Julius Fedorovicius
    • Aug 8 2017
    • Reply

    Check out this blog post by Lunametrics.

Mariana León
  • Sep 26 2017
  • Reply

I'm just so happy to find your post, that I wanted to say : Thank you so much!

Ella
  • Oct 4 2017
  • Reply

Hi Julius,

You just saved me probably weeks of work figuring out how to track Ajax forms, so I just wanted to thank you and say keep these awesome posts coming!

Cheers!

JULIAN
  • Oct 13 2017
  • Reply

THANKS SO MUCH

luvstuss
  • Oct 19 2017
  • Reply

Hi Julius,

Thank you for such a detailed article. Definitely, should add to bookmarks. However, I have an issue with implementation.

I tried to use the sixth option "FORM TRACKING WITH DOM SCRAPING". I've used CSS selector of the block with the message, appearing in the case of successful form submission. Nevertheless, DOM Element constantly returns "string 'null'". Could you kindly explain where the problem is?

http://london-plumber.co.uk/contact-us/

Thank you in advance.

    Julius Fed
    • Oct 21 2017
    • Reply

    Hey, the DOM variable isn't working for you because the technique I've described functions only when the page reloads and the success message is displayed. In your case, the message appears without reloading the page. Luckily, you can now try using Element visibility trigger in Google Tag Manager (which was released 3-4 days ago). I'll update this blog post in the future and will describe this new trigger in form tracking.

    Cheers
    Julius

      luvstuss
      • Jun 21 2018
      • Reply

      Hello again,
      I returned to the same issue with another client already.
      I created variable "Form Submission Message" where use ID as selection method and specified element ID. Btw should I put element ID with # or without #? Does it make a difference?
      Then by your previous recommendation, I created new trigger the type of Element Visibility, where as selection method specified the ID; "Minimum Percent Visible" = 100%; the condition for trigger fires on "Some Visibility Events" is "Form Submission Message" which is start from "Thank you for contacting us".

      But it doesn't work, gtm.elementVisibility doesn't load.

      https://versapak-anti-doping.com/contact-us/

      What am I doing wrong?
      Thank you in advance.

        Julius Fed (Fedorovicius)
        • Jun 21 2018
        • Reply

        Hey, if you chose selection method: ID, then # is not needed. # is needed if selection method is CSS Selector.

        Now, regarding your form. Since you form reloads the page and the success message is displayed on the page right away, I suggest using DOM Scraping method instead of Element Visibility. It's a bit risky, but if no one changes the ID, you should be good. Here's a guide how to track with DOM scraping https://www.analyticsmania.com/form-tracking-dom-scraping-google-tag-manager/

          luvstuss
          • Jun 22 2018

          Hi Julius,

          Thank you for the prompt response.

          Because the Variable "Form Submit Successfully" belongs to DOM Element type but Trigger used Page View type, therefore the value of the Variable didn't transfer earlier. As soon as I changed Trigger type from PV to DOM Ready, Tag started to fire on the page and receive the value of the variable. Now, this event can be tracked in the appropriate GA report, but it doesn't appear in Conversions/Goals report. However, that is another story.

          luvstuss
          • Jul 9 2018

          Hi Julius,

          on the page https://www.antiinondation.fr/contactez-nous/, the form reloads the page, and the success message is displayed. Therefore I decided using DOM Scraping method. If the form is successfully submitted appears notification "Merci de nous avoir contacté. Nous reviendrons vers vous sous peu". URL of the page stays the same.

          1 step: created variable "Form Submitted Successfully" - DOM element type; selection method - CSS selector.
          2 step: created trigger - Page view DOM Ready type; condition - variable "Form Submitted Successfully" start with "Merci de nous avoir".
          3 step: created tag - track type Event.

          Doesn't work. Could you help me with this?

          luvstuss
          • Jul 11 2018

          OK, I found solution https://www.analyticsmania.com/post/contact-form-7-event-tracking-with-google-tag-manager/. Big, big thank you!

Juan David Zapata
  • Oct 30 2017
  • Reply

Hi Julius, thanks for this post, and i have a question. I try to tag the thanks page of my e-commerce, i fired my trigger when the datalayer set a event named orderplaced, but when the user stay on the page and reload the trigger fired again, and thats mey not be happens. How i configure the trigger for the thanks page, for fired once time.

PD: I try configuring the analytics tag on once per page, does not work.

Thank you, best regard

    Julius Fed
    • Oct 30 2017
    • Reply

    Hey, after a visitor makes a purchase, set a cookie "justPurchased: true" (here's my tutorial https://www.analyticsmania.com/post/cookies-with-google-tag-manager/) and make it valid for 30 minutes.

    Then update to Thank You Page trigger with an additional rule:
    "justPurchased" does not equal to "true".

    If the cookie's value is equal to "True", then your tag will not fire.

    Hopes this makes sense.

Simon
  • Nov 20 2017
  • Reply

Hi Julius,

Well, first let me thank you for all the knowledge you are providing on your blog. It help me a lot to understand how gtm works.

Just a simple question, I followed all the steps of : #4. WRITE YOUR OWN FORM AUTO-EVENT LISTENER. It's working well if I keep in Gravity Forms the text confirmation option.

The bad thinks is that I'd like to redirect the user to a thank you page. There, the tag is not firing. Maybe it's because the JavaScript hook gform_confirmation_loaded is different ?

Of course, I could do a dom scraping, but I'd like to understand deeper why it's not working well. I don't want to put the thank you page as a trigger because I've several forms on my website.

Thanks a lot for your help,

Simon

    Julius Fed
    • Nov 21 2017
    • Reply

    Hey Simon,

    Yes, you are right. The event fires on the same page and if you redirect the user to another one, the form submission event might not have enough time to fire before the redirection.

    Regarding thank you page, maybe its URL is unique and you can use it in a Pageview trigger?

Samir
  • Nov 20 2017
  • Reply

Thanks for the post, Julius. It saved the day. Labas, Kaip tu?

    Julius Fed
    • Nov 21 2017
    • Reply

    Labas!
    You're welcome. It's a pleasure to serve my audience. If you haven't already, consider subscribing to my newsletter. Thanks.

Victor
  • Nov 25 2017
  • Reply

Hi Julius,
This is the most useful article I've ever read! It helps people like me with no coding experience and be super efficient with GTM!

Quick question: I'm following Method #3. (AJAX FORM TRACKING WITH GOOGLE TAG. MANAGER).

I've created a trigger that fires when dvl - attributes.response.messages.messages contains "Thank you for your enquiry".

However, this is an array not a string and therefore, does not return any results.
The array looks like this:
[
{
type: 'success',
text: 'Thank you for your enquiry. We endeavor to reply to you as soon as po
ssible!'
}
]

Is there a way to drill deeper and maybe create a variable that can find a string text inside the array. Something like:
dvl - attributes.response.messages.messages.[text] - would this work?

Here is one of the pages: https://www.strictlycomfort.com.au/snowshoe-hare-premium-throw-rug

Thank you in advance!

    Julius Fed
    • Nov 25 2017
    • Reply

    Hey, if you want to read array's data from the Data Layer, read the tip #3 from this blog post https://www.analyticsmania.com/post/pull-data-from-data-layer-google-tag-manager-tutorial/

      Victor
      • Nov 26 2017
      • Reply

      Perfect, I created a variable "dvl – attributes.response.messages.messages.0.text" and it worked!

      Thank you so much Julius!

      Cheers,
      Victor

Hampton Roese
  • Dec 1 2017
  • Reply

ok very new here. The first box asks if the form dispatches a submit event. How do I know if it does this? Basically, I am using Squarespace to track a donation page. The page has a donation form that will not submit unless all the required fields are filled out. When the donation is made, the URL refreshes but does not change. What should I do?

Thank you by the way

    Julius Fed
    • Dec 4 2017
    • Reply

    Hey, From what you've described, looks like you need to use either From Tracking Method No. 5 (Data Layer Event) or No. 6 (DOM scraping).

Dirk
  • Dec 12 2017
  • Reply

Hi, thanks for your great advice. I've read this post: https://www.analyticsmania.com/thank-you-page-tracking-google-tag-manager/
I've implemented everything in my Google TM. But the question I have now is: How can I view this information in my Google Analytics? I want to see the following: X submissions on a specific landing page.

    Julius Fed
    • Dec 16 2017
    • Reply

    Hey Dirk,

    One of the possible answers is this: in Google Analytics, go to Behavior > Events > Pages. Click the page you're interested in and you'll which events occurred on that page.

    Cheers

Fred Pike
  • Dec 22 2017
  • Reply

Excellent post. Informative, easy to follow, detail-rich. Thanks for writing this - nice job and I'm very impressed!

    Fred Pike
    • Dec 22 2017
    • Reply

    BTW - I was particularly impressed with the form auto-event listener example you walked through. I'm a big fan of #5 (dataLayer events), but this is a great overview of all options, and the decision chart was particularly useful!

Giovanni
  • Dec 22 2017
  • Reply

Fantastic, this work perfectly! Great post!

Penni
  • Dec 29 2017
  • Reply

First time to GTM and your post is without doubt the best I've found online, thanks for the detail!!

I'm sure I've followed it correctly, but it's not working for me so I've obviously missed something!

AJAX method, the lunametrics AJAX listener appears and works fine.

Yet when I submit the form on this page: https://www.kabocreative.com/contact/ it doesn't work. Under preview mode it's still showing as 'tags not fired on this page'.

Any hints massively appreciated, and thanks again!

    Penni
    • Dec 30 2017
    • Reply

    Fixed, amazing what a night of sleep does!

    In Caldera forms the response message is nested inside an html tag. Changed the dlv from attributes.response to attributes.response.html and it works.

      Julius Fed
      • Dec 30 2017
      • Reply

      Good job, Penni! It's important to understand that there is no standard when developers code AJAX forms. Therefore the response data might use different structures in different forms. In your case, you went one level deeper, from attributes.response to attributes.response.html which is a correct approach.

      Sometimes data structures are even messier when there are several objects within an array. I had one situation, where the data layer variable was attributes.response.0.success. That number (0) looks strange, right? I've described this in the 3rd tip of this blog post -> https://www.analyticsmania.com/post/pull-data-from-data-layer-google-tag-manager-tutorial/. So feel free to learn more :)

Ateh
  • Jan 2 2018
  • Reply

am trying to use the ajaxcomplete to track this form but as with previous comments the success message is within an object. I have followed your steps but in the DLV attributes.response.message they all come back as undefined so there is success message to search

http://cc.law.ac.uk/scholarships/postgraduate/register/

    Julius Fed
    • Jan 3 2018
    • Reply

    Hey, You need to create a variable attributes.response.Success (that's an uppercase S).

    Why? Because attributes.response contains another object and "Success" is one of the parameters. Therefore you need to go deeper and access Success parameter. Each level needs to be separated by a dot. As a result, the final key of the data layer variable is "attributes.response.Success".

    You can learn more about how to access data in the Data Layer by reading this blog post https://www.analyticsmania.com/post/pull-data-from-data-layer-google-tag-manager-tutorial/

      Ateh
      • Jan 3 2018
      • Reply

      Thanks Julius
      I started reading a bit more of the comments and started understand you could use the debugging feature to delve deeper and I identified the attributes.response.success which I had to set as true.
      This is a great post and thanks for your help. I will take a read of the article as I am having to use GTM a lot more.

raoul
  • Jan 12 2018
  • Reply

Hey just wanted to say thanks for this tutorial, it helped me a lot. The ajax container was super helpful, I was not aware of it.
Cheers

Vlado
  • Jan 19 2018
  • Reply

Hi,

I implemented THANK YOU PAGE TRACKING in GTM but I can't find a way do push the data to Google Analytics. Where in analytics can I see these conversions?

Mine main goal is to later link this with Adwords

Thanks

    Julius Fed
    • Jan 22 2018
    • Reply

    Hey, You can push data to Google Analytics with help of Universal Analytics Tag. I've described it in the "TAG + TRIGGER" section of this blog post.

    Cheers

Aldébaran
  • Jan 22 2018
  • Reply

Hi Julius,
First of all, thanks for this amazing tutorial, I've been following it for my personal website.
Very complete, and very well explained.
But, I am curently working on a form made in AJAX with an auto refresh (I installed LunaMetrics Plugin so I can get the ajaxComplete code).
The thing is, my attributes.response is a very large piece of code which changes so I cant' use it.
I decided to use attribute.response.ajax.submit which calls my form button (I suppose).
But it doesn't work
Is it possible to get some advices ?
Here's the link : http://fr.esterline-connection-technologies.com/en-en/search?category=4596&active_tab=part-number
( you have to click on "click here to refine your results" ).
sorry for my approximate english

    Julius Fed
    • Jan 22 2018
    • Reply

    Hey, there are hundreds of attributes.response.ajax.submit parameters in the response. Honestly, that response is huge and it will take way too much time to dig in. I would suggest keeping digging deeper.

    Maybe this blog post will give you some ideas https://www.analyticsmania.com/post/pull-data-from-data-layer-google-tag-manager-tutorial/

    Sorry, but debugging this response will take too much time while this week is super busy :(

    I've added a bookmark regarding this issue but I'm not sure when I'll be able to spare more time.

      Aldébaran
      • Feb 9 2018
      • Reply

      Hi Julius,
      Thanks for the blog post i'll check it out.

      Don't worry about this it's not "super" important. The response is probably going to change anyway, I asked the devs about it.
      I'll check it after that some development have been done.

      Have a good weekend and keep going ;).

Saba
  • Feb 9 2018
  • Reply

Hi Julius,

Very Interesting Posting. When I am trying to track my website form. I am getting an error. How to resolve this my contact form links is,

https://brandstory.in/get-a-quote/

    Julius Fed
    • Feb 9 2018
    • Reply

    Hey, what kind of error a(and where) do you get? And which form tracking method are you trying to use?

Jacob Birch
  • Feb 16 2018
  • Reply

Thank you so much for this - was having difficulty with some form submit tracking and didn't have easy access to developers. Step 3 (ajax container) worked wonders, thanks.

    Julius Fed
    • Feb 16 2018
    • Reply

    You're welcome, Jacob!

Byron
  • Feb 23 2018
  • Reply

Hi Guys,

Firstly, this tutorial is amazing - Wow, learnt so much in one tutorial. I'm trying this with the Divi Contact forms and the Lunar Metric Ajax script. The issue being is that I don't get a nice response code like you showed in your example, my response code appears to be the whole page.

If I use a basic submit form trigger in GTM then it works but it triggers regardless of successful submission or not. Then if I try putting the validation on it doesn't appear to ever fire. So the only way I've felt moving forward was to use the Lunar Metrics approach that you outlined below but the response code is literally the whole page in html rather than a nice response code like you guys got. Do you guys have any advice for that?

    Julius Fed
    • Feb 25 2018
    • Reply

    Hi, your case is not so rare, actually. Sometimes I see when the AJAX listener returns a huge chunk of code. Sometimes it returns another array of objects, etc. You'll have to find a way how to distinguish a regular AJAX response with the response of a successful form submission. Dig into that very long response code and find something useful.

    Sometimes, this blog post helps (check method 2 or 3) https://www.analyticsmania.com/post/pull-data-from-data-layer-google-tag-manager-tutorial/
    Cheers

Andrea
  • Feb 28 2018
  • Reply

I rarely give praise comments, but this article is simply awesome. Navigated through each step and managed to implement a custom solution for my client. Thank you!!

    Julius Fed
    • Mar 1 2018
    • Reply

    Glad to hear that!

Bhupen
  • Apr 18 2018
  • Reply

I am implementing Facebook Pixel code tracking for contact form using GTM, but its not working and unable to trigger. How to resolve this my contact form issue. website: https://immortaldreamz.com

    Julius Fed
    • Apr 18 2018
    • Reply

    Sorry, ignore the previous comment (if you received it via email). The form in the Contact page fires a data layer event called "contact" when a form is successfully submitted. Use that as a trigger. Here's a guide how to create a custom event trigger in GTM.

deven
  • Apr 27 2018
  • Reply

is this post still accurate? the date for this post is "march 19, 2018" but comments are from 2017. the reason i ask is because when creating a trigger in GTM, i don't see all of the "form variables" shown in the article. instead i only see "page element" variables and i'm unsure how to set those up. thanks in advance for your help!

    Julius Fed
    • Apr 27 2018
    • Reply

    Hey, This post was originally published in the 2017 but then updated several times, therefore publish date changed. Yes, this blog post is still pretty accurate (although, I'll have to update screenshots). In order to enable Form Variables, go to Variables > Built-in Variables > Configure and enable all form-related variables.

    Cheers

Mike
  • May 17 2018
  • Reply

Hello, what do i do when after form submits the response is blank?

Response: ' '

    Julius Fed
    • May 17 2018
    • Reply

    Hey, in that case forget about the AJAX listener because an empty response is unreliable. Instead, try using Element Visibility Trigger (when a success message appears, fire a tag) or ask a developer to use dataLayer.push when the form is successfully submitted.

    Read more on dataLayer.push here - https://www.analyticsmania.com/post/datalayer-push/

Natalia Lukianova
  • May 24 2018
  • Reply

Hi! I have the following problem: the GA tag fires with no problem when the preview mode but only then! when the preview mode is off, GA doesnt register any events! can you tell me what i could have done wrong?
Thank you

    Julius Fed
    • May 24 2018
    • Reply

    Hi, you need to publish changes.

      Natalia Lukianova
      • May 24 2018
      • Reply

      Can you indicate how to do it? I followed the instructions from this article https://www.analyticsmania.com/post/contact-form-7-event-tracking-with-google-tag-manager/ but cant find the instruction how to publish changes. Can you help me please?

        Julius Fed
        • Jun 1 2018
        • Reply

        In GTM, click the big blue SUBMIT button in the top right corner and follow the wizard steps.

julien muret
  • Jun 8 2018
  • Reply

Hi Julius

I still can't figure which tech should work for my site as the form is in overlay.
The developer just added : dataLayer.push({'event':'formSubmission','formType':'Registration'});

but I don't have any event in my preview mode gtm.submissionform
thanks for your help

    Julius Fed
    • Jun 8 2018
    • Reply

    Hey Julien,
    If a developer has added that code snippet, you should see "formSubmission" event in the preview mode after the form is successfully submitted. If it does not appear, ask him to add this one:

    window.dataLayer = window.dataLayer || []
    window.dataLayer.push({‘event’:’formSubmission’,’formType’:’Registration’});

    If it still does not appear, then the developer did not properly add the code and you should ask him/her to fix it.

      julien muret
      • Jun 8 2018
      • Reply

      Thanks Julius, don't you think is because I don't use the good event and formType name ? I put formSubmission and Registration because I found it on another explanations but this is no how our form is called.
      All I can see from "inspect element" is :
      form id
      register-modal-get-quotes
      button id
      register-modal-get-quotes-done

      Thanks,

      Julien

Catalina Stingaciu
  • Jun 13 2018
  • Reply

Hi,

I am curious about something. what would be the point in tracking a form based on thank you page? Since that url is unique and we are able to create destination goals in Analytics, why would we also need an event? Is there something that I'm missing?

Thanks,
Catalina

    Julius Fed (Fedorovicius)
    • Jun 15 2018
    • Reply

    Hey, this is not required. You can indeed use Destination Goals and will work perfectly fine. With events, you can pass up to 3 data points (without custom dimensions) - category, action, label. So I choose to utilize them.

    But that's up to you.

      Catalina Stingaciu
      • Jun 15 2018
      • Reply

      Thanks so much for your answer!

Youwei
  • Jun 13 2018
  • Reply

Hi Julius,

I have a question on the #2 thank you page type. You only mentioned if the answer is no to the question"can your users navigate back to the thankyou page?". But my obstacle is that people could actually re-navigate to the thankyou page after they summit the form. What should I do under this circumstance? or is there anyway to forbid people navigating back to the thank you page?

I will really appreciate it if I could get your reply!

Best,

    Julius Fed (Fedorovicius)
    • Jun 13 2018
    • Reply

    Hey, in that case, here's what you should do:
    - when a person submits a form, store a cookie in their browser
    - If the person navigates back to the thank you page, use that cookie as a blocking condition to not fire the conversion tag.

    Here's a guide how to set cookies with Google Tag Manager https://www.analyticsmania.com/post/cookies-with-google-tag-manager/

      Youwei
      • Jun 14 2018
      • Reply

      Thank you, Julius! This is really helpful! Thank you so much.

Matthias Kley
  • Jun 29 2018
  • Reply

Hi Julius,
thanks for this great post. i've implemented the ajax listener and It seems to work fine, but I don't get a form submission event in GA Real Time. I tried with attributes.respones.message and attributes.response.status. The website is https://www.erhardt-leimer.de/produkt/drehrahmensystem-drs07/

Do you have any idea whats wrong?

Thanks
Matthias

    Julius Fed (Fedorovicius)
    • Jun 29 2018
    • Reply

    Could you elaborate what do you mean "don't get a form submission event". You don't see any event? Or see something but it is undefined? Does the GA event tag fire after the form submission?

    You need to check what is the value of that Data Layer variable on ajaxComplete event.

    You can use attributes.response.status variable and it must be equal to "success". That should work fine.

      Matthias Kley
      • Jun 30 2018
      • Reply

      Thank you for your reply. Today I checked it again. All the form submissions I tested on Friday can now be seen in the behaviour-event report. But still I don't see any events in the real-time report (checked it again today).

        Julius
        • Jun 30 2018
        • Reply

        Check the tip #5 https://www.analyticsmania.com/post/google-analytics-real-time-reports-not-working/

        Also, check other suggestions.

Robert0
  • Jul 2 2018
  • Reply

Hi Julius,

always me.....

I have implemented n.5 method: tracking with data layer push

event is well tracked on GA real time. That's nice. All seems good.

Tag was pubished

I have just created the goal event (this is usually the easiest part), but in preview goal test it doesn't show any result and it doesn't track the conversion after test.

Configs seems good. I have also tried to change label event (in the conversion setting) from {{Page URL}} to the URL.

Any conversion. Many attempts done..

Thanks

    Julius
    • Jul 3 2018
    • Reply

    Do those goals appear in the the goal reports later? Not realtime but regular goal reports.

    I believe that have already collected some event data in the past. So when you creata a new event goal, use goal verification link. If the percentage is 0, your configuration is false. Maybe your condition is not correct.

      Roberto
      • Jul 3 2018
      • Reply

      Dear Julius,

      in the goal label would you insert {{Page URL}} or https://www.urlofthepageoftheevent.com/ ?

      Best Regards

        Julius Fed (Fedorovicius)
        • Jul 3 2018
        • Reply

        https://www.urlofthepageoftheevent.com/ of course :) {{Page URL}} will not work, because GTM passes the value of {{Page URL}}, not the actual name of the variable.

Krystyna
  • Jul 19 2018
  • Reply

Hi Julius,
Hope you are well.
Thank you for such a great post! I have implemented solution nr 3 with Ajax and it worked perfectly for my newsletter sign up.

I have a question: my client is using Bookly plugin on his wordpress website for bookings & payments. And again this is Ajax solution with the page just being refreshed with the payment confirmation message displayed.

I thought i could implement the same solution as with the newsletter but have trouble to get it work. I feel it might be to do with accessing the final message. So the message itself is located within a div with a class bookly-box.

After looking at Ajax complete data layer I tried to access it this way but the tag doesn't fire:
attributes.response.html.div.bookly-box

and then obviously create a variable with the relevant value/message.

is it the correct way of accessing it?

Thank you in advance for your help!

    Julius Fedorovicius
    • Jul 19 2018
    • Reply

    Hi, could you share a link to that form? Also, tell me the exact form you wish to track. That will help me debug faster.

      Vanessa
      • Jul 11 2019
      • Reply

      Hi Julius, so did you find a solution for tracking Bookly stuff? I think a lot of people would be interested.

        Julius Fedorovicius
        • Jul 12 2019
        • Reply

        No, I never received more information. Also, I wasn't looking into this proactively.

Krystyna
  • Jul 20 2018
  • Reply

Hi Julius, thanks for getting back to me!

The booking form is here: https://srisriayurveda.fr/prise-de-rendez-vous/
Basically each time you click 'next' button, the page URL doesn't change, only the message on the top-left changes. I tried to test the ajax solution yesterday for the message: 'Votre moyen de paiement préféré:' which comes up when you reach step 5-Payment.
This is the step when you have to pay so whatever message comes up when I reach point 6, after paying, I could use to track my conversions.

Thanks again for looking into this!

    Julius Fedorovicius
    • Jul 20 2018
    • Reply

    Oh, that response contains the entire HTML. In that case, continue using attributes.response (without html.div, etc.) variable in your trigger and try using "contains" or "matches regex (ignore case)" operator and, finally enter "Votre moyen de paiement préféré:" (without quotation marks) in the condition. That should work.

Krystyna
  • Jul 20 2018
  • Reply

Thank you Julius, unfortunately it didn't work :-( I tried both solutions. I have triple checked my variable/trigger/tag settings and they all seem correct:-) if it can't be done, that's fine. I found there is a possibility to create a thank you page with this plugin so can track my conversions from there. However if you maybe have an idea what could be checked additionally on this, let me know!Thanks!!

    Julius Fedorovicius
    • Jul 22 2018
    • Reply

    Send me an email with the shared link to the Preview and Debug mode (to julius @ analyticsmania.com). Also, please share the "view" access to that container (or "edit" would be even better).

    Cheers

      Krystyna
      • Jul 22 2018
      • Reply

      Hi Julius, email sent and access added :-) thank you!

Fakhruddin Lukmani
  • Jul 26 2018
  • Reply

Hu Juliuis,

Thank you for sharing such a Great Post with an in-depth instruction guide. Simply loved it :)

Now, when I am trying to check the implementation in Preview and Debug Mode, my return type is an object and not string for dlv - attributes.response. Any suggestions will be really helpful to rectify this out!!!

Form URL:-
http://surreyreadymix.co.uk/contact/

    Julius Fedorovicius
    • Jul 26 2018
    • Reply

    If you get an object, you need to dig deeper into that object and pick the correct value. Here's a guide where you can learn how to fetch a particular key from the object https://www.analyticsmania.com/post/pull-data-from-data-layer-google-tag-manager-tutorial/

    Read chapter #3.

      Fakhruddin Lukmani
      • Jul 26 2018
      • Reply

      Hi Juliuis,

      It worked :):):) I changed attributes.response to attributes.response.message

      Thanks for the Help!!!!

        Julius
        • Jul 26 2018
        • Reply

        Glad to help :)

Christelle's testing platform
  • Aug 31 2018
  • Reply

This is probably the clearest and easiest blog and guide I have ever read as a beginner for GTM. WOW! Thank you so much. That clarified sooo many terms and definitions for me. Thank. You!
Just to let you know, I just found out that Wix.com has implemented coding options within the website. So that gives me a whole lot more testing ground for all that tagging. Maybe worth looking at it for comparison?
Thanks again though!

    Julius Fedorovicius
    • Aug 31 2018
    • Reply

    Really, coding options? Sounds interesting. I'll have to dig deeper some time in the future.

Cyndee D
  • Oct 25 2018
  • Reply

Hi Julius, First of all, let me say if you were here, I would totally high 5/belly bump combo. I've been working on this for 3 days and thanks to you and your element visibility tip, it worked!
Now I have to figure out how to track form abandonment. I used this method and it captures the correct abandonment fields, but still fires even if the submit button is activated (I know it's because of the ajax) - https://www.analyticsmania.com/post/form-abandonment-tracking-google-tag-manager/
Have you guys written a post on how to tie it all together - track abandonment until the submit is fired? I can't seem to locate it anywhere. At least I got the submit button to work and for that I thank you very much!!!!

    Julius Fedorovicius
    • Oct 26 2018
    • Reply

    The solution that you mentioned in the comment supports only regular single-page forms that can be properly tracked with the GTM Form Submit trigger. AJAX forms are not supported and I'm not aware of such solution (yet). Since my own JavaScript knowledge is super limited, I cannot give you a custom solution.

    If the solution described in the post that you have mentioned does not work, it means that the requirements of that solution are not met. So you should doublecheck the list of requirements here

Lorie
  • Nov 16 2018
  • Reply

Your flowchart was exactly what I needed. Thank you so much!

Tanner
  • Nov 17 2018
  • Reply

I'm having the weirdest problem and maybe you can help. I am in the middle of setting up the form submission tracking, but before it's even live, I see gtm.formSubmit showing up in the Summary for the GTM Preview... any advice on why this is would be appreciated.

    Julius Fedorovicius
    • Nov 17 2018
    • Reply

    Hey,

    Facebook pixel is causing that. If you check the dataLayer on that gtm.formSubmit event, you'll see the Facebook URL. Make sure you actual Form Submission trigger is precise so that FB pixel's fake submission is not included.

Adrien Lafond
  • Dec 12 2018
  • Reply

I monitor all new stuff about GTM and this is by far the most comprehensive and understandable post on form tracking --for marketers-- I've ever read.

The part about creating a custom datalayer event in Gravity forms is incredible! Many marketers have somehow a few coding skills and can understand and achieve what you described.

Thanks for this excellent piece Julius!

Nadya
  • Dec 18 2018
  • Reply

Thank you so much for this post! I've used two of the methods and in both cases it was a big relief for me.

Andrea
  • Dec 20 2018
  • Reply

Julius, yours is the best tutorial I read online. However, I can't get my Thrive Leads forms to work with either method #3 or #4. Would you be willing to check the form in question? It's on this page: https://travelhonestly.com/free-stuff/
thanks so much
Andrea

    Julius Fedorovicius
    • Dec 20 2018
    • Reply

    I see that those popups are using AJAX, however, all of them return the same success message meaning that you cannot distinguish which form was submitted. In this case, I'd go with developer's help and ask him/her to push the form submission information to the dataLayer.

Armaan
  • Dec 24 2018
  • Reply

one of the best article. thanks for sharing

eric
  • Dec 28 2018
  • Reply

Thanks for the information, we got a dynamic mailchimp form to work!

rick
  • Jan 22 2019
  • Reply

Hello,many thanks for your work.
I am using the ajax method to test my form click tracking via tagmanger and everything seems to go well, but the "response" leaves no attribute, it's blank. So I do know what's going on next.

    Julius Fedorovicius
    • Jan 22 2019
    • Reply

    You mean the variable "attributes.response" is undefined? Have you checked what kind of value is stored in the data layer?

David
  • Feb 3 2019
  • Reply

Hi Julius,

Thanks so much for the detailed information. Really liked the decision tree! Helped me solve all my issues.

Anthony Mcloughlin
  • Feb 8 2019
  • Reply

Hey,

If Google Analytics (GA) is inside Google Tag Manager (GTM), you can create the goals in GA using the page destination option. So, if you send users to /form-thanks/ after they submit the form and setup a goal in GA to trigger on destination equal to /form-thanks/ that will track goals right?

    Julius Fedorovicius
    • Feb 8 2019
    • Reply

    Yeah, that will also work. Just don't forget to verify the goal before saving it :)

      Anthony Mcloughlin
      • Feb 8 2019
      • Reply

      Awesome! Thanks for the quick reply

Alessandro Sandini
  • Mar 6 2019
  • Reply

Hello Julius, I'm a big fan, your guides have helped me a lot in the past.
I'm switching from CF7 forms to the modules provides by GetResponse, an email marketing software; they're done with java script.

I thought the best way to track submissions would be to inspect the code, but the message - a green arrow - don't stay on the page for long, just a few second, and so I can't inspect the code.

Do you have any experience tracking this kind of forms? I can't possibly be the only one using it.

This is staging website I put this forms on >> http://phpstack-136743-751170.cloudwaysapps.com/en/contact/

I would highly appreciate any kind assistance you could give me.à
Thank you.

    Julius Fedorovicius
    • Mar 7 2019
    • Reply

    Hey, that form is in the iFrame (which is quite unfortunate). Do you have access to that form's source code and can you place GTM container inside of that form? If not, then it is impossible to track the form.

    I've just checked GetResponse documentation and they don't offer JavaScript API for their forms. This means that your only chance to track that form is to add GTM container code directly into that form.

    If that's not possible, the problem of the Green icon quick disappearance is irrelevant.

      Alessandro Sandini
      • Mar 7 2019
      • Reply

      Hello Julius, thank you for your prompt reply.

      Looking into the javascript code they sent me for integration, <script type="text/javascript" src="https://app.getresponse.com/view_webform_v2.js?u=zmtMU&webforms_id=SVZju"></script>,

      I've found this url =>https://app.getresponse.com/view_webform_v2.js?u=zmtMU&webforms_id=SVZju.

      If that's the source code you mentioned, then I think I'll have to ask them to grant me edit access to it.

      If they agree, I'll try to add the container as you have suggested.

      Thank you very much as always.

        Julius Fedorovicius
        • Mar 7 2019
        • Reply

        I very much doubt that they will agree. But you can try.

Dennis Megarry
  • Mar 28 2019
  • Reply

One of the things I would love to see in an article like this is form field tracking (advanced). I know I can get the value selected thru the dataLayer but to do real behavioral analytics, I also need to capture the previous value before the change. Our site is a SPA app so we do not have jQuery (does anyone still use it?). I could do a dataLayer push but have not figured out how to do that on a click event with an html snippet..

K
  • Apr 22 2019
  • Reply

Hey Julius.. this tutorial and website is amazing.. thanks so much. I had been struggling with this for a few weeks but the list is a great protocol to work through.. and the AJAX one half works.. It managed to trigger the tag, but it triggers even if the form was not not submitted successfully (i.e. incorrect email address or other error).. there seems to be an issue with the trigger not reading the variable correctly. The form is here - https://www.maxautolease.com/ ...if you can offer any insight i would greatly appreciate it. Thanks!

    Julius Fedorovicius
    • Apr 22 2019
    • Reply

    Hi, use Data Layer Variable attribute.response.success

    If its value equals to 'success' (without quotation marks), then the form was submitted successfully.

      K
      • Apr 22 2019
      • Reply

      Amazing.. I understand now. Thanks so much :)

Eda
  • Apr 24 2019
  • Reply

Hey Julius,

So the AJAX method seems to be working for me. Though I wish to add additional attributes. Like certain checkboxes that were checked and such. Is there a way to find/add these variables?

If possible I'd like to avoid contact the developper. Because in that case I might aswell just have them fix their current dataLayer.push script. (They only pushed constants instead of variables, which is quite useless for this real esate website..)

Thank you in advance!

    Julius Fedorovicius
    • Apr 24 2019
    • Reply

    Hey, you will need to contact developers regarding that information :)

Eda
  • May 2 2019
  • Reply

Hi Julius. I was wondering if the AJAX code snippet is still correct?

The method is working for me, but it triggers twice. Once on pageload, and once on succesful form submission. Ironically, both dataLayer details show a succes message. Therefore, I can no longer make a distinction.

    Julius Fedorovicius
    • May 2 2019
    • Reply

    Yes, it is correct. This means that your website sends an AJAX request every time a page is loaded. Maybe you can distinguish a successful submission by some other parameters in the response?

Marcin
  • May 18 2019
  • Reply

Hi,

Thank you for such an extensive article!

I'm using Elementor at my website, and its embedded form. Frankly speaking, I do not know which of the aforementioned methods suits best (the page is not reloading, there are no tickets, no thank you page, so submit event, have no idea about JS API).

I tried method 6, but the problem is that the tag GA - Contact Form Submission is being fired automatically, between Page View and DOM ready, and is not firing while submitting the form. The same situation with AJAX method, the tag is firing together with Page View, not reacting to form submission.

Do you have any thoughts/experiences with Elementor forms? Maybe I'm doing sth wrong? I'g be gratefull for any help! Thanks!

    Julius Fedorovicius
    • May 20 2019
    • Reply

    I remember someone asking for help with Elementor before and it looked like there was no JS API, the form was in the iframe, etc. All in all, the only possible solution was to somehow insert some additional tracking code in the form itself (if Elementor allows). If not, then that's bad.

    But honestly, I haven't worked with those forms, therefore, cannot give you precise advice.

Anton Gesmundo
  • May 22 2019
  • Reply

Hi Julius!

I followed #4. Track Forms with Element Visibility Trigger and the tag and trigger is set up fine. gtm.elementVisibility is firing right after DOM Ready, but the Google Analytics Tag fired only once after some delay of scrolling up and down the page (not immediately on the page load) and I couldn't get it to fire again after submitting another form.

    Julius Fedorovicius
    • May 27 2019
    • Reply

    Hey, Enable the "Observe DOM changes" checkbox and try again.

Julien VDC
  • May 22 2019
  • Reply

Hey Julius,

Like everyone else I'd like to thank you for posting publicly this guide, it's been a great help to understand further how GTM works and what you can do with it.

I currently testing the different approaches your suggesting (I think I might have to resort to #6 in my case...)... but I had questions concerning the DOM scraping which seems like you say a very weak solution:

- How would you proceed (if using DOM Scraping), if your site was multi-lingual and would thus display success messages in different languages depending on the user's preferred language?
- Also, would refreshing the page and thus display the message once again trigger it once again, thus counting twice..? How would you solve that?

Cheers,
Julien

    Julius Fedorovicius
    • May 27 2019
    • Reply

    Hey, your DOM scraping should depend on element classes, IDs, etc., not text. Therefore page translation should not have negative effects.

    As for the prevention of duplicate tracking, read this for inspiration https://www.simoahava.com/analytics/prevent-google-analytics-duplicate-transactions-with-customtask/

Ganesh
  • May 27 2019
  • Reply

Hi,

I cannot go to preview mode.

I am getting the following error for Ajax listener Custom script

Error at line 2, character 2: Parse error. primary expression expected

Thanks a ton in advance

    Julius Fedorovicius
    • May 28 2019
    • Reply

    Sounds like bad copying. Before you copy the code, switch to the plain-text mode (by clicking one of the buttons in that code block).

Ganesh
  • May 28 2019
  • Reply

Hi Julius,

Still getting same error even if i try with plain text mode.

    Julius Fedorovicius
    • May 29 2019
    • Reply

    Send me an email at [email protected] with more information, screenshots of your setup, of error that you're getting, shared access to your GTM container, GTM container ID, etc. The more you can provide, the better

Ganesh
  • May 28 2019
  • Reply

Hi Julius,

Still getting same error even if i try with plain text mode.

Ganesh

Shawn Williams
  • Jun 18 2019
  • Reply

Hi Julius,

Do you know of any resource like your Form Abandonment Tracking with GTM, but for Ajax Forms?

    Julius Fedorovicius
    • Jun 18 2019
    • Reply

    A solution that does not require developer's input? Sorry, no.

Liisa
  • Jul 3 2019
  • Reply

This is good insight on the topic. Have been struggling to track traffic sources and metrics for Pipedrive web form submission for ages. If I get it correctly then it appears there is no solution in Pipedrive web form case.

Marko
  • Jul 9 2019
  • Reply

I recently had to modify Lunametrics script to work on a single page app.
If anybody is interested then feel free to use it: https://gtm.marxdev.com/.

It works exactly like Lunametrics script but doesn't depend on jQuery and so should work on all websites.

Gabriel
  • Jul 11 2019
  • Reply

Dear Julius,

thanks for great content that you are sharing on this site and through your courses!

I've implemented successfully a lot of form tracking through element visibility trigger. However I'm struggling with one website. They don't have a permanent element that is visible after submitting the contact form. Just a 2 second pop-up appears at the top of the page, then it disappears. Is it possible to track it somehow?

    Julius Fedorovicius
    • Jul 12 2019
    • Reply

    Here's the guide I've just published. Inspired by your comment.
    https://www.analyticsmania.com/post/how-to-pause-javascript-and-inspect-an-element-that-quickly-disappears/

    Thanks!

Rafael
  • Jul 18 2019
  • Reply

You're the best! I have never seen so good blog post in my entire life! Keep blogging!

Marco Villasenor
  • Aug 1 2019
  • Reply

Hi Julius

I am trying to track cross domain from a link embedded in a button, but it is not working url: https://www.lillyplay.com.br

The link is in the button CADASTRE-SE JÁ

Your inputs Will be most appreciated

Regards,

Marco

    Julius Fedorovicius
    • Aug 2 2019
    • Reply

    That button is not a regular link. I suggest you talk with developers and ask them to decorate the link with the linker parameter.
    Or you need to know how to write JavaScript in order to find a way around.

Carlos Del Bortolo
  • Aug 8 2019
  • Reply

Came across your article by chance and it helped me A LOT in configuring form tracking using the Element Visibility Trigger. After spending loads of hours on Youtube trying to learn it, I've solved my problems in a few minutes :)

Gus
  • Aug 18 2019
  • Reply

Can you set a visibility trigger with an alert box? The form I'm trying to track only displays it after successful submit ( but I can't find the way to inspect it) I tried right-clicking on it to no avail.

The alert box looks like the one on this page (first alert box):

w3schools.com/js/js_popup.asp

    Julius Fedorovicius
    • Aug 18 2019
    • Reply

    Hey, no. That default browser array is not a part of the DOM (document object model), therefore, element visibility trigger cannot track it. Such form would require developer's input.

    As far as I saw on Stackoverflow, it would be possible to try to track the appearance of such alert with some custom JS, but it would not be guaranteed to work properly and also solutions I saw were tested just on Chrome.

    All in all, I'd go with developer's help on this one.

Sam
  • Aug 20 2019
  • Reply

🙏🙏🙏 Thank you Julius! Your article saved me hours of research and confusion. Appreciate the detailed descriptions, visual diagrams, and simplicity.

Sergiu
  • Aug 22 2019
  • Reply

Hi Julius,
want to start by saying thank you for all these great posts. I am learning the GTM based on your articles.

My question:
I need to track 2 events on the same page that are linked:
1. When a visitor clicks on a link (this is already working)
2. Record a Form submission on the same page but consider the outcome of 1.

In short:
If the visitor clicks on a link and submits the form => record Result1
If the visitors submits the form without performing the first action (click on a link) => record Result2.

Many thanks in advance

Julius Fedorovicius
  • Aug 22 2019
  • Reply

Use this for inspiration https://www.analyticsmania.com/post/trigger-groups-in-google-tag-manager/

    M Gomez
    • Sep 9 2019
    • Reply

    Hi Julius,

    I have a form that doesn't reload to a new url for confirmation and the tag will fire even if the form is not filled out. It works when using Element Visbiltiy but I've noticed that GA doesn't track it well within other browsers. I used your solution for Form Auto-Event Listener but I'm not getting the 'formSubmission' on the left hand side which leads me to believe that maybe something is wrong within my code, can you please help!

    Thanks!!

M Gomez
  • Sep 9 2019
  • Reply

I sent a previous message I just want to make sure it went through - please ignore this message if comments need to be approved prior to post. Thanks!!

M Gomez
  • Sep 9 2019
  • Reply

Hi Julius,

I have a form that doesn't reload to a new url for confirmation and the tag will fire even if the form is not filled out. It works when using Element Visbiltiy but I've noticed that GA doesn't track it well within other browsers. I used your solution for Form Auto-Event Listener but I'm not getting the 'formSubmission' on the left hand side which leads me to believe that maybe something is wrong within my code, can you please help!

Thanks!!

    Julius Fedorovicius
    • Sep 19 2019
    • Reply

    Have you tried AJAX form tracking?

Natalia
  • Sep 27 2019
  • Reply

Hi Julius,

Usually, I don't leave comments. But your article was really helpful. And I want to say thank you.

I struggled with event tracking via tag manager for one of my client while didn't find your flow scheme. It's really cool. Thank you very much.

Patrik Magoš
  • Oct 17 2019
  • Reply

Hello Julius,
first of all I have to say this article is amazing.
Really, this is how content marketing should look like.

Although it might sound like I was just trying to be nice to get help, I will ask for it anyway.

I have a page were ajax form is present. Everything went according to the article until the part with custom event attributes.response.
I've seen the response in data variable, everything looked great, but when I set it up (or tried URL attribute instead) it just didn't work after filling the form and switching from all page views to the custom trigger.
No idea, what can be the issue -_-

    Julius Fedorovicius
    • Oct 17 2019
    • Reply

    Not enough info. Share the link to your preview and debug mode and the url of the form. And the name of the tag that must fire after the form submission.

Kelsey Thompson
  • Nov 4 2019
  • Reply

The AJAX form tracking tutorial was life-saving! Thank you so much for making this information easy to understand, follow, and implement!

Drew Griffiths
  • Nov 13 2019
  • Reply

I'm also seeing the weird issue with facebook.com/tr/ as the Click URL for a form

    Julius Fedorovicius
    • Nov 13 2019
    • Reply

    Read this https://www.analyticsmania.com/post/why-is-there-a-gtm-formsubmit-event-on-every-page-view/

Leave a comment Cancel reply

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

 

Hi, I'm Julius Fedorovicius and I'm here to help you learn Google Tag Manager and GA (but mostly GTM). Join other 60000+ monthly readers and 12000+ newsletter subscribers in this exciting journey. Read more
Essential resources




Popular articles
  • 🔥 GTM Form Tracking: 7 Effective Methods
  • 🔥 dataLayer.push: The Guide
  • 🔥 GTM vs Google Analytics
  • 🔥 99 Things You Can Do with GTM
  • 🔥 Common GTM Mistakes
  • 🔥 Data Layer: Ultimate Guide
  • 🔥 60+ Custom JavaScripts for GTM
Analytics Mania
  • Google Tag Manager Courses
  • Google Tag Manager Recipes
  • Google Tag Manager Resources
  • Google Tag Manager Community
Follow Analytics Mania
  • Subscribe to newsletter
  • RSS feed
Recent Posts
  • Google Tag Manager Black Friday Sale is Here
  • Google Tag Manager Video Tracking Guide: Beyond Youtube
  • How to Track HTML5 Audio Player with Google Tag Manager and GA
Analytics Mania - Google Tag Manager and Google Analytics Blog | Privacy Policy
Manage Cookie Settings