How to Track Form Submissions with Google Tag Manager

Posted: July 16, 2021

Updated: Feb. 26, 2022

While you could hard code analytics and conversion tracking tags on your site, it's generally better to use Google Tag Manager (GTM) or an alternative such as Tealium or Mixpanel. There is no direct SEO advantage of using GTM, but it could improve page speed depending on how many tags you have, which might indirectly boost your SEO.

Install Google Tag Manager

These days, apps and websites tend to include multiple marketing and analytics codes such as Google Analytics, Google Ads, Google Optimize, Mixpanel, and Facebook Pixel, to name a few common ones. GTM works well even with non-Google products. Now, you can clean up all of those separate third-party tracking codes, and just copy and paste one instead - the GTM container code. In theory, you can even use one GTM container for multiple domains, although the best practice is to have one GTM container per domain especially for large sites.

Google previously recommended placing the container code immediately before the opening body tag, but now is a little different. GTM has split the container, so the first part should be placed in the head, and the second part in the body.

GTM provides you with the exact code to copy and paste to your website. You can find the installation code along the top navigation under Admin → Container Settings → Install Google Tag Manager. For sites hosted on WordPress, use the Insert Headers and Footers plugin or insert the code directly from wp-admin/theme-editor.php, or Appearance > Theme File Editor.

The first part is a script tag, which includes a JavaScript function that loads your container to the page. It creates a new script tag, and sets the source to the URL to your container. This should be placed immediately inside of the head to optimize tracking. The higher up in the page the snippet is, the faster it is loaded.

The second part is a no script tag, and it's actually optional. This is just a backup tag that allows you to track users without JavaScript, so it's not important in most cases. It's telling the browser: if the user does not have JavaScript enabled, then render an iframe version of the container to the page.

Add DataLayer

DataLayer is used to feed data to GTM such as clicks, form submissions, purchases, user ID, login method, etc. The best practice is to add dataLayer above the container. Otherwise, it can cause issues such as the container code overwriting dataLayer.

Form Submission Tracking

Here are several methods for tracking form submissions with GTM, generally in order of easiest to most complicated. Since the feasibility of these methods will depend on how your site is coded, I created this flowchart on Canva that shows the relevant tracking methods for each situation. Detailed explanation follows the flowchart.

Form Submission Tracking with GTM - flowchart

If your users are redirected to a confirmation page after the form submission, you can simply track page views for that page. Otherwise, you'll need to dig deeper in the page's source code to find some variable that GTM can recognize. At this point, if you are tracking Google Ads conversions, remember to add All Elements in addition to All Pages as a second trigger for your Conversion Linker tag.

Contact form submission with confirmation message

If the form displays a unique confirmation message upon submission, you can use the Element Visibility trigger type in GTM. The contact form on my website is an example of this situation, because the "Thank you for contacting Rei Morikawa" message in the bottom right appears upon successful completion of the form.

If the element has an ID, it's easier to use Selection Method: ID. Otherwise, use CSS selector, which is explained later in this post. Also in the trigger configuration settings, regardless of which selection method you choose, check Observe DOM changes and change Minimum Percent Visible to 1 percent.

Button Click Tracking

If you form has neither a confirmation page or message, you'll need to track button clicks in GTM. This time, we'll be using the Click - All Elements trigger type. There are several possible variables that can be used for this method, but Click ID or Click Classes is probably the most common. Generally, Click ID might be more reliable, but it depends on your dev environment.

To see which variables are available for you, use preview & debug mode in GTM or check dataLayer in the Console. Note that Click Element cannot be used for this method, but it is explained in the following section on CSS selectors.

CSS Selectors

If none of the above methods so far have not worked, it's time to use CSS selector. You'll need to use CSS selector for some of the following situations.

  1. You are using the Element Visibility trigger and Selection Method: ID is not available.

  2. There are no unique variables available for tracking button clicks using Click - All Elements trigger type.

  3. The button is made up of multiple elements.

We've already seen situations 1 and 2, so let me just elaborate about 3, using the same example of the contact form on my website. Here is the source code for the "Send" button.

<div id="comp-k0kz041v" aria-disabled="false" class="_2UgQw">
	<button aria-disabled="false" data-testid="buttonElement" class="_1fbEI">
		<span class="_1Qjd7">SEND</span>

The background and text elements are separated. However in GTM, we want to treat them the same, because we want to track form submissions regardless of whether the user clicked precisely on the "Send" text, or anywhere else within the button.

This is possible with CSS selectors, which allow you to write complex conditions for selecting certain elements on a website. To implement this method, start by creating a Click - All Elements trigger, but this time choose Click Element matches CSS selector for the variable. For this example, either of the following the CSS selectors should work.

 #comp-k0kz041v, #comp-k0kz041v *
 ._2UgQw, _2UgQw *

Deciphering the above CSS selectors:

  • # indicates id; . indicates class

  • Comma indicates OR condition

  • * is wildcard

The first CSS selector in plain English means, element with ID comp-k0kz041v or any child (or child of child, etc.) of that element. The second one means, element with class _2UgQw, or any child of that element. Note that spaces will break your CSS selector, so you can simply replace any spaces within the ID or class with a period.

This is a basic setup example, but here is an expanded list from W3schools of CSS selectors for reference: CSS Selector Reference

Trigger Groups

By default, if you add multiple triggers to a single tag on GTM, they are treated as an OR function. The tag will fire as soon as any of the triggers has its condition met. To treat multiple triggers as an AND function, use Trigger Groups, which were introduced on GTM recently in March 2019. Trigger Groups will be useful if you have multiple forms with the same confirmation message, or multiple buttons with the same class.


There's several ways to check if your GTM tags are set up and firing correctly. First, check your website's source code and make sure that the GTM script is implemented by searching for gtm.js. If that wasn't the problem, you can check the other solutions below.

Preview & Debug Mode

As the name suggests, preview & debug (P&D) mode in GTM allows you to preview your site and check which tags are firing, and what data is sent to third-party platforms. Please note that P&D was updated in October 2020 to shift from 3rd party cookies to first party storage, so if you are following a guide or video that was published before that, it will look different.

As a freelancer or agency-side marketer, you might not have access to the client's GTM account. Even as an in-house specialist, there might be a different department that controls GTM. However, there are several methods to verify GTM even if you can't access the account.

Tag Assistant Legacy

Tag Assistant Legacy is a Google Chrome extension by Google for GTM, an extremely useful tool for testing and debugging. You can use it to troubleshoot GTM, as well as Google Ads, Analytics, and DoubleClick implementation.

Test Conversions

You can also simulate a test conversion - the way to do this depends on your specific conversion event. For example, if the conversion event that you want to test is pageviews on GA, just open the page in another tab and check GA. If you aren't sure because there are other pageviews, you can add a test utm such as:


In some PPC platforms like Facebook, you can just visit the confirmation page to manually simulate a conversion, and confirm it in the conversion events page. For Google Ads conversions, add the following parameter to the end of your URL to simulate a click.


Custom Code

Setting up tracking between Google services like Analytics and Ads is pretty straightforward, and the built-in variables should be enough to get the job done. But if you're using GTM to connect your website to third-party platforms like Pardot or HubSpot, you'll need to add custom html or JavaScript via new user-defined variables. Note that custom JavaScript must be nested in an anonymous function with return value.