Google Analytics 4 (GA4) tells you who visits your website and what they do there. Google Tag Manager (GTM) loads GA4 and any other tracking tag (a small script from a tool such as Meta, LinkedIn or Hotjar), so you don’t edit your site’s code every time.
This guide covers both setups: a WordPress site and a plain HTML website using native script. Plan for about 20 minutes.
In short
- Install Google Tag Manager once, then add GA4 as a tag inside it.
- Never install GA4 both directly and through GTM, or every page view counts twice.
- With EU visitors, set up Consent Mode v2. Then check in GTM Preview and GA4 Realtime.
Which setup should you choose?
GTM + GA4 (recommended). Install GTM once, then add GA4 as a tag inside it. Every future tag is added in GTM, not in your code.
GA4 only (gtag.js). Paste one GA4 snippet. This is fine for a simple site that will never need other tags.
Pick one route. If GA4 is installed directly and also through GTM, every page view is counted twice.
Before you start
Install Google Tag Manager
Option 1: GTM4WP plugin (easiest)
- Go to Plugins → Add Plugin and search for GTM4WP (Google Tag Manager for WordPress).
- Install and activate it.
- Open Settings → Google Tag Manager, paste your GTM- ID and save.
The plugin adds both GTM snippets to every page for you.
Option 2: Site Kit by Google
Site Kit is Google’s official plugin. Install it, connect your Google account, and turn on the Analytics and Tag Manager modules. It places the code for you and shows basic reports inside WordPress.
Option 3: Your theme’s header code field (no plugin)
Some themes have a setting for custom scripts in the page head. If yours does, paste the GTM head snippet below there and save.
<!-- Google Tag Manager -->
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','GTM-XXXXXXX');</script>
<!-- End Google Tag Manager -->
The noscript part only matters for visitors with JavaScript turned off, so GTM works without it.
Option 4: Child theme code (developers)
Add both snippets with WordPress hooks in your child theme‘s functions.php, so a theme update never removes them.
// Child theme functions.php
add_action( 'wp_head', function () { ?>
<!-- Google Tag Manager -->
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','GTM-XXXXXXX');</script>
<!-- End Google Tag Manager -->
<?php }, 1 );
add_action( 'wp_body_open', function () { ?>
<!-- Google Tag Manager (noscript) -->
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-XXXXXXX"
height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
<!-- End Google Tag Manager (noscript) -->
<?php } );
On a plain HTML site you paste two snippets from GTM → Admin → Install Google Tag Manager into every page, or into the shared header and footer include if your site has one. Google’s install guide shows the same placement.
Step 1: Head snippet
Paste this as high in the <head> as possible.
<!-- Google Tag Manager -->
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','GTM-XXXXXXX');</script>
<!-- End Google Tag Manager -->
Step 2: Body snippet
Paste this immediately after the opening <body> tag.
<!-- Google Tag Manager (noscript) -->
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-XXXXXXX"
height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
<!-- End Google Tag Manager (noscript) -->
Where they go
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<!-- 1. GTM head snippet: as high in <head> as possible -->
...
</head>
<body>
<!-- 2. GTM noscript snippet: right after the opening <body> tag -->
...
</body>
</html>
Replace GTM-XXXXXXX with your own Container ID.
Add GA4 inside Tag Manager
Google recommends the Initialization – All Pages trigger so the Google tag fires before your other tags. See Google’s Google tag setup guide.
GA4 only, without GTM
If you chose the simpler route, paste the GA4 snippet from GA4 → Admin → Data streams → your stream → View tag instructions. Use it instead of GTM, never next to a GA4 tag in GTM.
<!-- Google tag (gtag.js) -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXXXX"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-XXXXXXXXXX');
</script>
- WordPress: paste it into your theme’s header code field, or let Site Kit add it.
- HTML site: paste it into the
<head>of every page.
Consent Mode v2 for the EU
Under the GDPR, analytics cookies need consent first. Google Consent Mode v2 lets Google tags wait for that consent.
- Use a consent banner that supports Consent Mode, such as CookieYes, Cookiebot or Usercentrics.
- Turn on Google Consent Mode in the banner’s settings, with all categories denied by default.
- Make sure the banner loads before, or together with, GTM.
Google tags check consent themselves and adjust once the banner sends the visitor’s choice. This is general guidance, not legal advice.
Check that it works
More help from Google: GTM Preview mode, GA4 DebugView and the Realtime report.
Common mistakes
- Double tagging: GA4 installed directly and through GTM, so page views double.
- Container not published: GTM changes stay in the workspace until you click Publish.
- Old cached pages: visitors keep getting HTML without the snippet.
- An old UA- ID: Universal Analytics no longer collects data. GA4 IDs start with G-.
- Testing with an ad blocker on: blockers stop GA4 requests, so nothing shows up.
- Consent never granted: if you decline cookies while testing, GA4 won’t record you.
Frequently asked questions
Do I need both GA4 and Google Tag Manager?
No. GA4 is the analytics tool. GTM is optional, but it makes adding and changing tags much easier later.
Is Google Tag Manager free?
Yes. The standard versions of both GTM and GA4 are free.
Will GTM slow down my website?
The GTM container loads asynchronously (in the background), so its own impact is small. The tags you add inside it matter more, so keep them lean.
How long until data shows up?
Realtime reports update within seconds. Standard reports can take 24 to 48 hours.
Where do I find my Measurement ID?
In GA4 go to Admin → Data streams and open your web stream. The ID starts with G-.
Want us to set up your tracking?
We install GA4 and GTM, set up consent mode and build the events that matter for your business.