← Run an audit
Home / Checks / 2 of 11
critical severity

GA4 is not installed twice

Two GA4 tags on one page double-count every event. Traffic figures look plausible while every conversion number is inflated and every ROAS calculation feeds wrong data to Smart Bidding.

Why this matters

Two GA4 tags on one page double-count every event. Traffic figures look plausible while every conversion number is inflated and every ROAS calculation feeds wrong data to Smart Bidding.

How this tool detects it

The tool counts two loads separately: occurrences of gtag/js?id=G-… (GA4 itself) and occurrences of gtm.js?id=GTM-… (a Tag Manager container). They are judged independently and never summed.

That separation matters. One GTM container plus one GA4 snippet is a normal setup — GTM is what loads GA4, so seeing both is not duplication. Only GA4 loading twice counts as a duplicate install.

The tool also compares how many distinct measurement IDs appear. Two or more different G- IDs means two properties are running at once, even if each is loaded exactly once.

A duplicated GTM container is a related but separate problem, and it is reported under the Tag Manager check rather than here — the damage looks the same but the fix is different.

Where this check can mislead you

Static analysis has limits. These are the cases where this particular check will report a result that does not match reality — worth knowing before you act on it.

Examples

WrongWrong: GTM is in place, but the leftover hard-coded GA4 was never removed
<script async src="https://www.googletagmanager.com/gtm.js?id=GTM-ABC123"></script>
<!-- GA4 is already configured inside GTM, and hard-coded here as well -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-ABC123"></script>
<script>
  gtag('js', new Date());
  gtag('config','G-ABC123');
</script>

The most classic GA4 migration mistake. GA4 was added to the template during the migration, but the original hard-coded copy was never removed. Every pageview now reports twice.

WrongWrong: the same GTM container is included twice
<!-- the theme template already had one, and here is a second -->
<script async src="https://www.googletagmanager.com/gtm.js?id=GTM-XYZ789"></script>
<script async src="https://www.googletagmanager.com/gtm.js?id=GTM-XYZ789"></script>

Common after switching themes without clearing the old template. Every tag and trigger inside the container runs twice.

CorrectCorrect: loaded via GTM, and only that one
<script>window.dataLayer=window.dataLayer||[];</script>
<script async src="https://www.googletagmanager.com/gtm.js?id=GTM-ABC123"></script>
<!-- the GA4 configuration lives in the GTM UI, not hard-coded in HTML -->

Only GTM is in the HTML; GA4 is loaded from inside the container. This is the recommended approach.

How to fix it

  1. Search your source for gtag/js?id= and gtm.js?id= and count each separately.
  2. If a GTM container exists, check whether GA4 is already configured inside it. If it is, delete the hard-coded GA4 snippet from the HTML.
  3. Search for all distinct G- IDs. If more than one exists, decide which is current and remove the rest — and deactivate the retired properties in the GA4 admin so data stops flowing into them.
  4. If the same GTM ID appears several times, check four usual sources: the theme template, the page builder, a footer widget, and plugin injection.
  5. After cleanup, test a specific URL with Search Console's URL Inspection tool and confirm the rendered HTML contains only one copy.

Verify it worked

After making changes, confirm delivery rather than assuming. These steps require your Google login, which is exactly why this tool stops short of them.

Related checks

One thing static analysis cannot tell you: this page reads published code, so it shows what is installed, never what actually fires. To confirm delivery, use GTM Preview and GA4 DebugView — both require your Google login.

Check whether your site has this problem — no login required.