What problem GTM actually solves
Before tag managers existed, adding any tracking to a website meant adding code directly to the site's HTML. Google Analytics snippet goes in the header. Facebook pixel goes in the header. LinkedIn Insight Tag goes in the header. Google Ads conversion tracking goes on the thank-you page. Hotjar goes in the header. Every new tool means a developer edit, a deployment cycle, and another piece of third-party JavaScript loading on every page.
GTM replaces that with a single snippet of code — the GTM container — added to your site once. After that, every tracking tag, pixel, and script is managed inside GTM's interface, not in the site's codebase. Marketers can add and modify tracking without developer deploys. Tags can be tested before going live. Everything is versioned, so you can roll back if something breaks.
The three core concepts: Tags, Triggers, Variables
Tags
A tag is a piece of code that GTM injects into your page. It might be a GA4 event, a Google Ads conversion, a LinkedIn Insight Tag, or a custom HTML snippet. GTM has built-in templates for the most common tools, so you don't have to write the JavaScript yourself — you fill in fields and GTM generates the code.
Triggers
A trigger tells GTM when to fire a tag. Common triggers: on every page view, on clicks matching a specific CSS selector, when a form is submitted, when a custom event is pushed to the data layer, or when a user scrolls to a certain depth on a page.
Triggers are where most of the logic lives. A GA4 "page_view" tag fires on an "All Pages" trigger. A GA4 "generate_lead" event fires on a "Form Submission" trigger scoped to a specific form ID. Getting triggers right is the difference between accurate tracking and garbage data.
Variables
Variables capture dynamic values that get passed into tags. The URL of the current page. The text content of the element that was clicked. The value of a data layer variable pushed by your application. Without variables, every tag would be hardcoded — you'd need a separate GA4 tag for every page, instead of one tag that passes the current page URL dynamically.
GTM has built-in variables (page URL, click text, referrer) and lets you define custom variables that read from the data layer. The data layer is a JavaScript array on your page that your site can write to, and GTM can read from. It's how your application communicates with GTM.
The data layer
The data layer is the communication channel between your website and GTM. When something meaningful happens on your site — a form is submitted, a product is viewed, a user logs in — your site can push an object to the data layer describing what happened. GTM picks that up, triggers can listen for it, and variables can extract values from it.
A simple data layer push looks like this:
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
event: 'form_submit',
form_name: 'contact',
lead_type: 'demo_request'
});
GTM can trigger a tag when it sees the form_submit event, and a variable can read the lead_type value and pass it to GA4 as an event parameter.
Preview mode: the most important feature
Before you publish any changes in GTM, you can preview them. GTM's preview mode opens your website in a special debugging session where you can see every tag that fired, which trigger caused it to fire, and what data was passed. This lets you verify that your tracking is working correctly before it affects real data.
I never publish a GTM container change without going through preview mode first. The consequences of getting it wrong — double-counting conversions, firing tags on the wrong pages, missing key events — can corrupt weeks of data before anyone notices.
Versioning and rollbacks
Every published GTM container is a version. If a change you publish causes a problem, you can roll back to the previous version in seconds. This is a significant advantage over managing tracking code directly in your website — if you push broken JavaScript to production and don't have an easy rollback mechanism, you're in trouble.
What should and shouldn't go in GTM
GTM can inject any JavaScript into your page, which means it can technically be used for almost anything. But not everything should be in GTM.
Good for GTM: Analytics tracking (GA4), ad pixels (Google Ads, Meta, LinkedIn), conversion tracking, chat widget snippets, A/B testing tools, heatmap tools, consent management integrations.
Not good for GTM: Core site functionality (navigation, forms, anything user-facing). Security-sensitive code. Code that needs to execute before the page renders — GTM loads asynchronously, so anything in GTM fires after the page has begun loading. Performance-critical scripts that need to be server-side or inline.
Who should manage GTM
GTM access should be controlled. Anyone who can log into GTM and publish a container can inject arbitrary JavaScript into your website. That's a significant security surface. Limit publish permissions to people who understand what they're doing.
The ideal GTM administrator is someone who understands HTML and JavaScript at a basic level, thinks carefully about data quality, and tests every change in preview mode before publishing. "Our marketing intern set it up" is a phrase I've heard before seeing some genuinely broken tracking setups.
Need GTM set up properly?
I set up GTM containers with clean tagging architecture, data layer standards, consent mode integration, and documentation — so whoever manages it next can understand what's there and why.
Get a quote