---
title: "How to add Google Tag Manager to WordPress (both snippets)"
description: "Add Google Tag Manager to WordPress the right way: which box each GTM snippet goes in, how to check it is live, and the no-plugin functions.php route."
pubDate: 2026-09-26
updated: 2026-09-26
source: https://adminkeep.com/guides/add-google-tag-manager-wordpress/
---

Google Tag Manager hands you two snippets and two instructions: paste the first "as high in the `<head>` of the page as possible", and the second "immediately after the opening `<body>` tag". WordPress has no box for either. The obvious move, pasting them into the theme's `header.php`, works until the next theme update overwrites the file and your tracking quietly stops.

This guide shows how to add Google Tag Manager to WordPress so it stays put: where each of the two snippets goes, how to add them with a plugin or without one, how to check the tags are live, and how Google Analytics 4 fits in.

## Before you start: your container ID

If you don't have a container yet, go to [tagmanager.google.com](https://tagmanager.google.com/), create an account, and add a container with **Web** as the target platform. Tag Manager then shows the install code. You can open it again any time from **Admin → Install Google Tag Manager**.

Every container has an ID in the form `GTM-` followed by letters and numbers. Both snippets contain it. In this guide it appears as `GTM-XXXXXXX`; yours will be different, so always copy the code from your own container rather than from a page like this one.

## The two GTM snippets, and where each one goes

The first snippet is a script. It loads Tag Manager, which then loads every tag you set up in the container:

```html
<!-- 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 second is a fallback for visitors whose browser runs no JavaScript. It is a hidden `<iframe>` inside a `<noscript>` tag:

```html
<!-- 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) -->
```

In WordPress terms, the two places Google asks for have names. The head is printed by the `wp_head` hook. The spot right after `<body>` opens is the `wp_body_open` hook, which WordPress added in version 5.2 for exactly this kind of snippet.

| Snippet | Where Google asks for it | WordPress hook | Adminkeep box |
|---|---|---|---|
| The `<script>` | As high in `<head>` as possible | `wp_head` | **Head** |
| The `<noscript>` | Immediately after `<body>` opens | `wp_body_open` | **Body open** |

Some guides put the noscript part in the footer instead. Browsers still load it there, so for the rare visitor with JavaScript off it mostly works, but it isn't where Google asks for it, and there has been no reason to put it there since `wp_body_open` arrived.

## Add Google Tag Manager to WordPress with Adminkeep

[Adminkeep](https://wordpress.org/plugins/adminkeep/) is a free plugin made of small features that each have one switch. Its [Header & Footer Code](/header-footer-code/) feature adds three boxes that match where snippets ask to go, and keeps them with the site rather than the theme. If you don't have Adminkeep yet, [installation](/docs/installation/) takes a minute.

1. Go to **Settings → Adminkeep** and switch on **Header & Footer Code** in the **Appearance** group.
2. Open **Appearance → Header & Footer Code**.
3. Paste the first snippet, the `<script>`, into the **Head** box.
4. Paste the second snippet, the `<noscript>`, into the **Body open** box.
5. Press **Save code**.

<figure class="ak-shot">
  <img src="/screenshots/header-footer-code-screen.webp" alt="Header & Footer Code screen under Appearance with Head, Body open and Footer code boxes" width="1200" height="1050" loading="lazy" decoding="async" />
  <figcaption>Appearance → Header &amp; Footer Code: the GTM script goes in Head, the noscript in Body open.</figcaption>
</figure>

What happens once it's saved:

- **The code prints exactly as you pasted it**, on every front-end page, whichever theme is active. The Head box prints near the top of `<head>`, before your theme's stylesheets and scripts. Body open prints straight after `<body>`.
- **The admin and the login page are left out**, so a mistyped snippet can't stop you getting back to the screen to fix it.
- **It survives theme updates and theme switches.** The code is stored in a site option, not in a theme file.
- **Each box shows who last changed it and when**, which helps when the numbers in your reports jump and you want to know whether anyone touched the tags.
- **Only administrators who are allowed to post unfiltered HTML can open the screen.** On multisite that is super admins only.

Leave the Footer box empty for GTM. It is for things like chat widgets that ask to be loaded at the end of the page.

## Add Google Tag Manager without a plugin

If you'd rather not use a plugin, WordPress's hooks let a theme print both snippets. Put this in a **child theme's** `functions.php`, with your own container code pasted in:

```php
// Google Tag Manager: the main snippet, early in <head>.
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 );

// Google Tag Manager: the noscript fallback, right after <body> opens.
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
} );
```

The `1` on `wp_head` runs the function early, before the stylesheets and scripts WordPress prints later in the head.

This works well, and it is a fine choice for a developer who keeps the theme in version control. Know the trade-offs before you pick it:

- **It needs a child theme.** Edit the parent theme's `functions.php` or `header.php` and the next theme update overwrites your change without a word. If you don't have a child theme, creating one is a job in itself.
- **It goes with the theme.** Switch to a different theme and the snippets stay behind, just as [custom CSS does](/guides/wordpress-custom-css/).
- **Changing a tag means editing a file.** That is a file upload or a deploy, not a text box. If the theme file editor is switched off on your site, which is a sensible [hardening step](/guides/disallow-file-mods-vs-disallow-file-edit/), you need file access.
- **A PHP typo can take the site down.** A missing bracket or quote in `functions.php` is a critical error on every page until the file is fixed, usually over FTP or SSH.

Editing `header.php`, the method in many older tutorials, has the same problems and one more: in a child theme it means copying the whole template, so you stop getting the theme's own fixes to that file.

## Check that it's live

Don't trust a save button. Check the page itself.

1. **Open the site in a private window.** It is logged out and skips most browser caching.
2. **View the page source**: right-click and choose **View Page Source**, or press Ctrl+U (Cmd+Option+U on a Mac). Search for your `GTM-` ID. It should appear twice: once in the `<head>`, and once in the `<noscript>` just after `<body>`.
3. **If it isn't there, clear your caches.** A caching plugin, your host's page cache or a CDN such as Cloudflare can keep serving the page as it was before you saved. Purge them and look again.
4. **Test with Tag Assistant.** In Tag Manager, press **Preview**. It opens [Tag Assistant](https://tagassistant.google.com/), which loads your site and shows that the container connected and which tags fired on each page.
5. **Publish the container.** Tag Manager on its own tracks nothing. Tags you add in the container only reach visitors after you press **Submit** and publish a version.

If the head snippet shows but the noscript one doesn't, your theme doesn't call `wp_body_open()`. Block themes and classic themes made since WordPress 5.2 do; an older classic theme may not. The main snippet is the one that does the tracking, so everything still works for visitors with JavaScript. If you want the fallback too, ask the theme's author to add the hook, or put the noscript snippet in the Footer box instead.

## Adding Google Analytics 4

Once Tag Manager is on the site, GA4 is added in Tag Manager, not in WordPress:

1. In Google Analytics, open **Admin → Data streams**, choose your web stream and copy the **Measurement ID**. It starts with `G-`.
2. In Tag Manager, create a tag of type **Google tag**, paste the Measurement ID, and set the trigger to **Initialization - All Pages**.
3. Preview it with Tag Assistant, then **Submit** to publish.
4. Visit the site and watch **Reports → Realtime** in Analytics. Your visit should show within a minute.

If GA4 is the only tag you need, you can skip Tag Manager altogether. Analytics gives you its own snippet, the Google tag, under **Admin → Data streams → your stream → View tag instructions → Install manually**:

```html
<!-- 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>
```

It goes in the same place as GTM's main snippet: the **Head** box, or `wp_head` in a child theme. There is no body part.

**Use one route per GA4 property, not both.** A property installed through Tag Manager and through the Google tag counts every page view twice. The same goes for plugins that add Analytics for you, such as Site Kit or a theme's own "analytics code" option: if one of those is already sending data to the property, remove it before adding the snippet.

## Things to know before you publish

**Your own visits are counted.** The snippets print for every visitor, logged-in administrators included. Exclude your own traffic in GA4 instead: define your IP address as internal traffic (**Admin → Data streams → your stream → Configure tag settings → Define internal traffic**), then set the Internal Traffic filter to **Active** under **Admin → Data filters**.

**Consent rules may apply.** If your visitors are in the EU or the UK, analytics and advertising tags usually need the visitor's consent before they run. Tag Manager supports this through consent mode, together with a consent banner. Adminkeep prints the snippets you give it and doesn't manage consent itself.

**One container per site is usually right.** Several containers on one page work, but each adds weight, and tags split across containers are hard to keep track of. Add new tags inside the container instead of pasting new snippets into the site.

## Questions people ask

### Where does the Google Tag Manager noscript code go in WordPress?

Immediately after the opening <body> tag. WordPress marks that spot with the wp_body_open hook, which block themes and classic themes made since WordPress 5.2 call. Adminkeep's Body open box prints there; in a child theme, hook a function to wp_body_open.

### Can I add Google Tag Manager to WordPress without a plugin?

Yes. In a child theme's functions.php, print the main snippet on the wp_head hook and the noscript snippet on wp_body_open. Don't edit the parent theme's header.php or functions.php: the next theme update overwrites them.

### Do I need Google Tag Manager to use Google Analytics 4?

No. GA4's own Google tag (gtag.js) is a single snippet that goes in the head. Tag Manager is worth it when you manage several tags, or want to change them without touching the site. Use one or the other for a given GA4 property, not both, or every visit is counted twice.

### How do I know Google Tag Manager is working on my WordPress site?

Open the site in a private window, view the page source and search for your GTM- container ID: it should appear twice, once in the head and once after the body tag. Then press Preview in Tag Manager, which opens Tag Assistant and shows which tags fire on each page.
