The WordPress way to install GTM is clunky
You want to manage all analytics, pixels, and event tracking from one place. That's what GTM is for, but installing it typically means another plugin or theme edit.
The canonical WordPress paths are: install an analytics plugin (comes with admin pages, updates, subscription nags), paste the snippet into functions.php (breaks when you switch themes), or set up Google Tag Manager as middleware (overkill for one pixel).
What most people do instead
How to add Google Tag Manager to WordPress without a plugin
GTM is two snippets: a script in the <head> and a <noscript> right after the opening <body> tag. A must-use plugin can output both, on the wp_head and wp_body_open hooks:
// wp-content/mu-plugins/gtm.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>
<?php } );
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>
<?php } ); Swap GTM-XXXXXXX for your container ID. Two catches on top of the usual file maintenance:
- The
<noscript>part relies onwp_body_open, which older themes do not fire, so the body tag is missed on those. - The usual ones too: theme-tied in
functions.php, hardcoded ID, fires for admins, no consent gating.
The command places both parts correctly and adds consent-awareness, with nothing to maintain.
A better way: one command, one ID, tracking live
Run enable gtm with your Container ID. The command auto-registers as a startup command so the tracking snippet outputs on every page load. No theme edit, no plugin, no GTM middleware.
Shown in advanced mode, where commands start with tp. In easy mode you type the same command without the tp prefix.
Consent-aware flag included. Pass -consent_aware=true and the pixel only fires when your cookie-consent plugin's gate has been accepted. Works with any standard WP consent plugin that sets a cookie flag.
How it works
The command hooks wp_head with the Google-provided tracking snippet, then auto-registers itself in Startup Commands so the tracking stays active across requests. Re-running with a different ID updates the existing entry. Disable from Startup Commands to remove.
tp enable gtm -cid=GTM-XXXXXXX| Parameter | Value |
|---|---|
-cid (required) | Container ID (format: GTM-XXXXXXX) |
-consent_aware | true to only fire after cookie consent (checks standard consent cookie) |
| Scope | Auto-registered as startup command, runs on every frontend page load |
| Where to find the ID | Google Tag Manager → Container Admin |
| Can be used in |
Real example
Your analytics team manages tracking via GTM. Until now you've been adding individual plugins (GA4, Facebook Pixel, Hotjar), each one a separate WordPress plugin. You want to consolidate into GTM. Run tp enable gtm -cid=GTM-ABC123 and every future tag goes through GTM instead. One container, all your tracking.
Goes further with TrueCommander
Frequently asked questions
wp_head and wp_body_open hooks, as shown above. The trade-offs are a hardcoded ID, no consent gating, and a body tag that older themes may miss. TrueCommander places both correctly in one command.<head>, and the <noscript> iframe goes immediately after the opening <body> tag (the wp_body_open hook). The noscript part is what fails most often when done by hand.