
Author Name
Emtiaz Hossain
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.
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.
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.
JS - Is Page Reload.{{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.back_forward from the allowed navigation types, adjusting the .includes() check to whichever navigation types should be blocked for that specific tag.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:
window.hasFormSubmitted style flag, as used in the Contact Form 7 tracking pattern, guards against this specifically.getEntriesByType('navigation')) reliably distinguishes reload, fresh navigation, and back/forward history traversalCheck 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.
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.
Discussed this on LinkedIn
Found this helpful?
Drop a comment on the LinkedIn post – I read every reply and love connecting with tracking folks.
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.
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.
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.
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.