← All Guides

Simple Form Tracking with Google Tag Manager: Four Methods Ranked, With Code, for GA4, Google Ads and Meta

The four ways to track a form submission in GTM, ranked by reliability: a dataLayer success event, a thank-you page, success message visibility, and the built-in form trigger. Code for each, how to pick, and how to send one event to GA4, Google Ads and Meta.

Atiqul Islam
Written by Atiqul Islam

Tracking & analytics specialist. 278+ GTM, GA4 and server-side tracking projects for clients in the US, UK and Australia.

Rather not do this yourself? I set this up for clients every week. Free 15-minute audit, no obligation.

Book a Free Audit

Form tracking is the most common tracking request and the most commonly wrong. The usual setups fire on the button, fire on a thank-you page anyone can open, or fire twice. This guide ranks the four methods, gives code for each, and shows the single event that feeds GA4, Google Ads and Meta.

The Goal

One dataLayer event, form_submit_success, pushed once per successful submission, carrying the form name, form ID and, where available, the submitter's email and phone. Everything downstream hangs off it.

Method 1: dataLayer Push on Confirmed Success

The best option. The form tool's success callback, or your own code's successful server response, pushes the event:

window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
  event: 'form_submit_success',
  form_tool: 'custom',
  form_name: 'Contact',
  form_id: 'contact-main',
  user_email: 'name@example.com',
  user_phone: '+15551234567'
});

Every major form tool exposes a success hook, and this site has guides with the exact listener for Elementor, Gravity Forms, WPForms, Fluent Forms, HubSpot, JotForm, Typeform and Tally. For a custom form, add the push in the code that handles the server's success response.

Method 2: Thank-You Page

If the form redirects to a dedicated page after success:

  1. Create a Page View trigger where Page Path equals /thank-you.
  2. Fire the GA4, Google Ads and Meta tags on it.
  3. Add a noindex meta tag to the page, remove it from the sitemap and navigation.
  4. If several forms share the page, pass a parameter in the redirect such as ?form=contact and read it with a URL variable.

Weakness: anyone who bookmarks or refreshes the page counts again. Mitigate with Count set to One in Google Ads and with a cookie check in GTM that skips the tag if the same visitor converted in the last few minutes.

Method 3: Success Message Visibility

For forms that show a message in place and give you no hook, use the Element Visibility trigger:

  1. Find the CSS selector of the success message container, for example .form-success or .wpcf7-mail-sent-ok.
  2. Create an Element Visibility trigger: selection method CSS selector, that selector, fire once per page, minimum visible 50 percent, and enable Observe DOM changes.
  3. Push a dataLayer event from a small Custom HTML tag on that trigger so the rest of the setup stays the same:
<script>
window.dataLayer.push({
  event: 'form_submit_success',
  form_tool: 'visibility',
  form_name: {{Form Name Lookup}},
  form_id: 'unknown'
});
</script>

Weakness: the selector changes if the theme or plugin updates, and an error message that reuses the same container class will count. Check the selector is unique to success.

Method 4: Built-In Form Submission Trigger, Validated

GTM's Form Submission trigger listens for the browser's submit event. It fires before validation and before the server responds, so on its own it overcounts. It is acceptable only when:

Even then, a server-side validation error after submit will have already counted. Treat it as a last resort.

The Downstream Tags

Create Data Layer Variables for form_name, form_id, user_email and user_phone, and a Custom Event trigger on form_submit_success.

To fire a different Google Ads conversion for a specific form, duplicate the trigger with a condition form_id equals that form.

Spam and Quality

Test

  1. GTM Preview. Submit the form with test data. Confirm form_submit_success appears once with the right form name and that GA4, Google Ads and Meta each fired once.
  2. Submit with a required field empty. Nothing should fire.
  3. Submit twice quickly. One conversion.
  4. For Method 2, open the thank-you URL directly and note that it fires; that is the known weakness.
  5. Check GA4 DebugView, Google Ads Diagnostics the next day and Meta Test Events.

Outcome

One event per real submission, feeding three platforms with the same definition of a lead, with the submitter's details attached for matching. From here, the CRM stage guides on this site show how to tell the platforms which of those leads turned into customers.

Frequently Asked Questions

Which method should I use?

A dataLayer push on confirmed success whenever you or your developer can add it, because it fires once and only after the server accepted the form. Thank-you page tracking is second. Success message visibility is a solid fallback for forms you cannot modify. The built-in form submission trigger is last resort and must be validated.

Why is tracking the submit button wrong?

The click happens before validation. Every empty required field, every spam attempt, every double click becomes a conversion. Your lead count inflates and the ad platforms optimise toward people who click buttons.

Can one trigger feed GA4, Google Ads and Meta?

Yes, and it should. One dataLayer event named form_submit_success triggers a GA4 generate_lead tag, a Google Ads conversion tag and a Meta Lead tag. Three platforms, one definition of a lead.

How do I track which form was submitted when a site has several?

Include form_name and form_id in the event. Use them as GA4 parameters and as trigger conditions when a specific form should fire a specific Google Ads conversion.

What about spam?

Add a honeypot or reCAPTCHA to the form so spam never reaches success, and fire tracking only on confirmed success. Spam that passes both will still count, so monitor entries.

Want This Done Right the First Time?

Book a free 15-minute audit call. I'll review your setup, show you what is broken, and tell you exactly what it takes to fix it.

Chat Now