GA4 is installed
Why this matters
Universal Analytics stopped processing data in July 2023 and all history was deleted in July 2024. A site still on UA has been measuring nothing for two years.
How this tool detects it
The tool looks for two GA4 signals in your source: the measurement ID (the G- prefix followed by 6–20 alphanumeric characters) and the gtag.js load URL (googletagmanager.com/gtag/js?id=G-…). Either one present means GA4 is installed.
It separately checks three Universal Analytics leftovers: a reference to analytics.js, a ga('create') call, and any UA-12345-1 style property ID. A hit on any one of them counts as residual UA code.
The order of these checks is what makes the result meaningful. The tool confirms GA4 exists first, then looks for UA residue, and only concludes "no analytics at all" if neither is present. That distinction separates three situations that need completely different fixes: never migrated, half-migrated, and never had analytics.
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.
- GA4 configured only inside GTM is invisible to this tool. If the GA4 tag lives entirely in the container and the HTML contains only the GTM snippet, the check reports a warning rather than a failure — static analysis genuinely cannot tell you whether GA4 is configured in the container. This is the recommended setup, so treat it as unverified rather than broken, and confirm in GTM Preview.
- Server-side GA4 cannot be confirmed. GA4 hits sent through a server-side container do not appear in page source. If your architecture includes a server-side layer, this check reports a warning rather than a failure — the absence of GA4 code in the HTML says nothing about what your server sends.
- Dynamically injected tags in single-page apps are not visible. A React or Vue app that inserts gtag after a route change leaves no trace in the static source this tool reads.
Examples
<script async src="https://www.googletagmanager.com/gtag/js?id=G-1A2B3C4D5E"></script>
<script>
gtag('js', new Date());
gtag('config','G-1A2B3C4D5E');
</script>
The property ID matches the config call, and the snippet loads once. This is the most common and most reliable form.
<script src="https://www.google-analytics.com/analytics.js"></script>
<script>
ga('create', 'UA-12345-1', 'auto');
ga('send', 'pageview');
</script>
UA stopped processing data in July 2023 and all history was deleted in July 2024. This code still downloads, but collects nothing.
How to fix it
- Create a GA4 property in Google Analytics if you do not have one. Note that a GA4 property and a Universal Analytics property are separate systems — a UA property cannot be upgraded in place.
- Copy your
G-XXXXXXXXXXmeasurement ID from Admin → Data Streams → Web. - Place the gtag.js snippet inside
<head>, as early as possible. - Remove every
analytics.jsreference andga('create')call from the page. This is the step most often missed — plenty of sites still carry the old code months after migrating. - Re-scan with this tool and confirm both the GA4 and dead-UA checks pass.
- Last step: confirm in Google Search Console that the Traffic report has started receiving data. The first figures usually appear within 24–48 hours.
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.
- Open Admin → Data Streams in GA4 and confirm the web stream exists with the same measurement ID you found on the page.
- Check the last 24 hours in the Search Console Performance report. After a first-time setup, data usually takes 24–48 hours to appear.
- Watch events arrive in GA4 DebugView (Admin → Data Streams → Debug). This step needs your Google login and is the one thing static analysis cannot replace.
Related checks
Check whether your site has this problem — no login required.