Emtiaz
ServicesCase StudiesTestimonialsAboutFAQBlogs
Audit and Reporting6 min read

Fixing Double Form Submission Tracking in GTM

Emtiaz Hossain

Author Name

Emtiaz Hossain

Last Edit : Jul 20, 2026, 04:36:00 PM
Fixing Double Form Submission Tracking in GTM

TABLE OF CONTENTS▼
The Usual Suspect: Reload, Not a Real Second SubmissionThe Fix: Detect Reload vs. Fresh NavigationWiring It Into the FixOther Common Double-Fire Causes Worth Ruling OutKey TakeawaysFrequently Asked QuestionsHow do I know if double counting is a reload issue versus a duplicate tag issue?Does this reload check work for AJAX forms that don't navigate to a separate thank-you page?

Contents

0%
The Usual Suspect: Reload, Not a Real Second SubmissionThe Fix: Detect Reload vs. Fresh NavigationWiring It Into the FixOther Common Double-Fire Causes Worth Ruling OutKey TakeawaysFrequently Asked QuestionsHow do I know if double counting is a reload issue versus a duplicate tag issue?Does this reload check work for AJAX forms that don't navigate to a separate thank-you page?

A client reports form submits are being double-counted, GA4 or the CRM shows two leads for what was clearly one person filling out one form once. Before touching triggers or dedup logic, the first thing to check is one specific, very common cause: the tag firing again on page reload.

The Usual Suspect: Reload, Not a Real Second Submission

Forms that redirect to a "thank you" page (or that reload after a non-AJAX submission) share a specific failure mode: if the tracking tag is set on the thank-you page load itself (rather than tied strictly to the submit action), a browser refresh, a back-button-then-forward navigation, or even certain prefetch behaviors can re-trigger the page load and fire the conversion tag a second time for the same original submission.

The Fix: Detect Reload vs. Fresh Navigation

javascript
function(){
return window.performance.getEntriesByType('navigation').map(function(nav){ return nav.type}).includes('reload')
}

This is built as a GTM Custom JavaScript variable, returning true if the current page load was a reload rather than fresh navigation. The Performance.getEntriesByType('navigation') API exposes exactly how the current page was loaded, whether the user navigated to it (navigate), reloaded it (reload), went back/forward through history (back_forward), or arrived via a prefetch (prerender). Checking specifically for 'reload' catches the most common false-positive case: a customer or a curious client hitting refresh on the thank-you page.

Wiring It Into the Fix

  1. Add the Custom JavaScript variable above to GTM, name it something like JS - Is Page Reload.
  2. On the conversion tag firing on the thank-you page, add a trigger exception (or a blocking trigger condition) checking {{JS - Is Page Reload}} equals false, so the tag only fires on the original, fresh page load, never on a subsequent reload of the same URL.
  3. If back/forward navigation is also inflating counts, extend the check to also exclude back_forward from the allowed navigation types, adjusting the .includes() check to whichever navigation types should be blocked for that specific tag.

Other Common Double-Fire Causes Worth Ruling Out

This reload check solves one specific, common cause, but it's not the only source of duplicate conversion counts. Before assuming this is the fix, also check:

  • ▸Two tags actually configured to fire on the same event. The most literal cause of duplication: an old tag left active alongside a newer replacement, both listening for the same trigger. A quick audit of every tag firing on the relevant trigger in GTM's tag overview usually surfaces this immediately.
  • ▸A form's own submit handler firing more than once per click. Some plugin or custom JavaScript submit listeners attach the event handler multiple times if the script loads more than once on the page (a common side effect of duplicate script tags, or a script re-injected by a page builder). A window.hasFormSubmitted style flag, as used in the Contact Form 7 tracking pattern, guards against this specifically.
  • ▸AJAX forms with a retry on network failure. If a form's own JS retries a failed submission automatically, and the tracking tag is tied to the retry attempt rather than the final confirmed success, a slow network can produce two pushes for what was ultimately one successful submission from the user's perspective.

Key Takeaways

  • ▸Before assuming duplicate conversions mean a logic bug, check whether the tag is tied to a page load that can be reloaded, rather than strictly to the original submit action
  • ▸The Performance Navigation Timing API (getEntriesByType('navigation')) reliably distinguishes reload, fresh navigation, and back/forward history traversal
  • ▸Audit for genuinely duplicate tags configured on the same trigger, this is often the real cause and is faster to rule out than debugging JavaScript
  • ▸If a form's own submit handler can attach more than once, a simple submission flag prevents it from pushing to the dataLayer twice for one real submission

Frequently Asked Questions

How do I know if double counting is a reload issue versus a duplicate tag issue?

Check GTM's tag overview for every tag firing on the relevant trigger first, that rules out or confirms a literal duplicate tag in under a minute. If only one tag is configured, add the reload-detection variable and check its value in GTM Preview while manually refreshing the thank-you page, if it returns true on refresh and the tag fired anyway, the reload check will fix it directly.

Does this reload check work for AJAX forms that don't navigate to a separate thank-you page?

Not directly, the Navigation Timing API only reflects full page loads. For AJAX forms that display a success message without navigating, the safer approach is a submission flag (like window.hasFormSubmitted) scoped to the current page session, which blocks a second dataLayer push regardless of whether a reload occurred.

#GTM#event deduplication

Discussed this on LinkedIn

Found this helpful?

Drop a comment on the LinkedIn post – I read every reply and love connecting with tracking folks.

View on LinkedIn

Not Sure If Your Tracking Is Costing You?

Book a free 30-minute call. I will review your current tracking setup, show you where conversions are leaking, and tell you exactly what I would fix.

More Blog Posts

View all
The GA4 & GTM Audit That Found a Shopify Store's Google Ads Data Was 2x Inflated
Audit and Reporting

The GA4 & GTM Audit That Found a Shopify Store's Google Ads Data Was 2x Inflated

A full GA4/GTM/Google Ads audit on a UK Shopify store spending £18,000+/month found duplicate conversion tags inflating reported purchases 2x, a dropped GCLID at checkout, and misconfigured variables silently degrading Enhanced Conversions. Here's the audit, the fixes, and the migration off a legacy GTM setup before Shopify's deprecation deadline.

Complete LinkedIn Conversion Tracking Setup
Advanced Tracking

Complete LinkedIn Conversion Tracking Setup

How a UK marketing agency's LinkedIn Insight Tag upgrade turned into a full conversion audit, catching duplicate tags and stale triggers across eight lead-gen conversions.

Tracking WPForms Submissions with GTM
Advanced Tracking

Tracking WPForms Submissions with GTM

WPForms has two submission modes, AJAX and non-AJAX, that need completely different GTM tracking patterns. Here's the real code for both, plus the validation logic non-AJAX forms need.

Emtiaz
EmailLinkedInPrivacyTerms

© 2026 Emtiaz Hossain