Helpful information ...
Google Tag Manager Setup: A Complete Guide to GA4 and Consent
Google Tag Manager Setup: A Complete Guide to GA4 and Consent
By the end of this guide, you'll have a working Google Tag Manager setup connected to GA4, with a correctly structured dataLayer and Consent Mode configured. The path there runs through eight steps: creating an account and container, embedding the code, the dataLayer, GA4 configuration, events, ecommerce, consent management, and testing in Preview mode. Further down, you'll also find the most common mistakes that wreck your data before you even notice.
In short:
- For reliable tracking, it's essential that the dataLayer already holds basic data — like page type and IDs — before the GTM code even loads, so data is sent correctly from the very first interaction.
- The connection between GTM and GA4 needs a configuration tag with the correct Measurement ID, firing on every page, which is also what enables proper tracking of every subsequent event.
- For ecommerce setup, you need to push a structured
itemsarray to the dataLayer with full product details, otherwise you'll lose purchase and revenue data.- Consent management with Consent Mode requires correct GTM configuration alongside your CMP, to avoid losing important data from the very start of a visit.
- Before publishing, use the preview feature to check in real time that tags fire in the right order and that events show up in GA4, which prevents duplicated or lost data.
Table of Contents
- Creating an account and container in GTM
- Embedding the GTM code and correctly initializing the dataLayer
- Connecting GTM to GA4: the configuration tag
- Setting up GA4 events in GTM: variables, triggers, and parameters
- Ecommerce settings: the dataLayer items array and the GA4 purchase tag
- Consent Mode and consent management in GTM
- Testing in Preview / Tag Assistant and publishing changes
- The most common mistakes and how to fix them
- When to leave GTM setup to experienced hands
- What actually matters in a GTM setup
- Sources
- Frequently asked questions
Creating an account and container in GTM
Everything starts at tagmanager.google.com, where you select Create Account and then Create Container. These two steps set up the basic structure where you'll later add tags, triggers, and variables.
A container isn't a one-size-fits-all thing. When creating it, you choose a type based on the platform you're actually measuring:
- Web for standard websites and online stores (the most common choice);
- iOS and Android for mobile apps;
- AMP for accelerated mobile pages;
- Server for server-side tracking, when you want to move data processing away from the browser.
Name your container after the site's domain, for example "mycompany.si Web," since you'll often end up managing multiple containers for different projects within a single account. When creating it, Google also asks whether you want to anonymously share usage data with Google. This choice doesn't affect your measurements — it's just aggregated statistics on tool usage.
Before embedding the code, check one more thing under Admin > Container settings: the time zone and currency, if the system requires them, and who will have access to the container. This saves you from having to fix these settings later, once the container is already full of tags.
Embedding the GTM code and correctly initializing the dataLayer
Once you create the container, Google Tag Manager gives you two code snippets. The first goes as high as possible in the <head>, the second right after the opening <body> tag. This order isn't a cosmetic detail: the head code starts GTM as early as possible, while the body code makes sure tracking still works for users with JavaScript disabled.
Before the GTM snippet loads, the dataLayer needs to already exist as a variable, otherwise you'll lose the first events. The process is simple:
- Above the GTM code in the head, add
window.dataLayer = window.dataLayer || [];— this pattern prevents overwriting any data that already exists, which happens if you usewindow.dataLayer = [...]instead. - Right after that, add
dataLayer.push({...})with basic page attributes, such aspage_type,user_id, ortransaction_idif the page is an order confirmation page. - Only then does the GTM snippet load, reading this data during initialization.
These early attributes matter because GTM can use them in its very first triggers — measuring the first page of a visit, say, or checking whether a user is logged in.
Pro tip: If your site generates a lot of advertising traffic and you use multiple tracking tools at once (Meta Pixel, TikTok Pixel, Google Ads), consider a server-side container. A web container remains the right choice for smaller and mid-sized sites, where transparency and a quick setup outweigh the added complexity of a server-side version.
Connecting GTM to GA4: the configuration tag
Before GA4 can register a single event, you need a Configuration tag. This is a tag of type Google Analytics: GA4 Configuration, where you enter the Measurement ID from your GA4 property (in the format G-XXXXXXX). This tag should fire on every page, typically with an All Pages trigger.
Within the configuration tag, you can set default parameters that apply across the entire site:
- Currency, if you know all your visitors pay in a single currency;
- User properties, such as a user segment or subscription type;
- Send a page view event when this configuration loads — leave this option on, unless you're sending the page view manually through a separate event, which is common for single-page applications (SPAs).
The Configuration tag and Event tags play different roles. The Configuration tag tells GA4 where to send data and what the default rules are; Event tags are what actually send real interactions, such as clicks, form submissions, or purchases. If the configuration is missing or incorrect, Event tags will appear to work, but the data won't be correctly attributed to the right property in GA4.
For conversion modeling and first-party data, the rule is: the more stable and consistent your configuration, the more reliably GA4 can model missing data when consent is declined. A poor configuration at the start shows up later in every report, from attribution to advertising audiences.
Setting up GA4 events in GTM: variables, triggers, and parameters
Once the configuration is in place, next comes creating a GA4 Event tag. In the Configuration Tag field, select your existing Configuration tag, and in the Event Name field, enter the event's name, such as generate_lead or add_to_cart.
To access data from the dataLayer, you need a Data Layer Variable. Create one for each individual parameter, for example:
dlv_form_idforform_id;dlv_button_textfor the text of the clicked button;dlv_page_typefor the type of page where the event happens.
Naming is where most projects fall apart. A consistent convention — lowercase with underscores throughout, for example (click_button, not ClickButton or button-click) — makes analysis in GA4 significantly easier, since it avoids the same event ending up split across three different names.
Typical events and their triggers:
- generate_lead — a Form Submission trigger when a contact form is submitted;
- add_to_cart — a Custom Event trigger listening for a dataLayer event from the site (e.g.
addToCart); - view_item — triggered on loading a product page, often with a condition based on the URL or
page_type.
Pro tip: Before creating your tenth event, write out a list of every event and its parameters on paper. Businesses that skip this step often find, three months later, that they have five variations of the same event in GA4 and not a single usable report.
Ecommerce settings: the dataLayer items array and the GA4 purchase tag
For online stores, the most data gets lost right at the purchase, since that's the page carrying your revenue-generating traffic. GA4 expects the items structure as an array within the dataLayer object, not as separate variables for each product.
The process for correctly setting up the purchase event:
- On the order confirmation page, send a
dataLayer.pushwith an object containingtransaction_id,value,currency, and anitemsarray, where each product has its ownitem_id,item_name,price, andquantity. - In GTM, create a Data Layer Variable named
ecommerce.itemsthat reads the entire array. - In the GA4 Event tag for the
purchaseevent, under the Ecommerce section, enable the option for the tag to use data from theecommercevariable, and add theitemsarray as an Event Parameter. - Check that
valueandcurrencyare always present, since without them GA4 can't correctly display revenue in its ecommerce reports.
If you're migrating from the older Universal Analytics Enhanced Ecommerce, most errors stem from the old field names (id, name, list) instead of the new GA4 names (item_id, item_name, item_list_name). The structure looks similar, but GA4 simply won't read fields with the wrong names.
Also check that currency isn't hard-coded as "EUR" across every page, if your store sells in multiple countries. A single push with the wrong currency will distort your entire revenue report, and you often won't notice until the end of the month, when the numbers don't match accounting. A detailed look at the whole ecommerce tracking process is available in the Moxy Web guide to GA4 ecommerce.
Consent Mode and consent management in GTM
Consent Mode v2 recognizes four types of consent: ad_storage, analytics_storage, ad_user_data, and ad_personalization. When a user declines consent, Google tags don't stop sending data entirely — instead, they send anonymous, cookieless pings that let GA4 do basic modeling.
Consent Mode isn't a substitute for a consent banner. It's an API that connects your consent solution (CMP) to Google tags and tells them how to behave based on the user's choice.
In GTM, the first step is enabling Consent Overview in the container settings. Then add a Consent Initialization trigger, which ensures the default consent state is set before any other tags fire. Without this trigger, you risk GA4 and Google Ads tags firing before the user's consent state is even known.
A common mistake is adding extra consent checks directly onto individual Google tags. Google Analytics, Google Ads, and Floodlight already have consent logic built in, so a manually added condition can actually block the automatic adjustment Consent Mode would otherwise handle on its own. The fix is to remove any extra exception triggers and let Consent Mode handle it.
When working with a CMP (Cookiebot, OneTrust, Usercentrics, and similar), watch out for one thing in particular: asynchronous loading. If the consent state arrives too late, because the CMP loads after tags have already fired, you'll lose part of the first events on the page. The fix is combining the Consent Initialization trigger with a CMP event that pushes a consent update to the dataLayer the moment the user makes their choice.

Testing in Preview / Tag Assistant and publishing changes
Before publishing anything, click Preview in the top-right corner of the container. GTM opens a new window where you enter the URL of the page you want to test, connecting your browser to a debug session.
- Open the page in a new tab and check that Tag Assistant Connected appears at the bottom of the window.
- In the debug view, check the firing order of your tags: Consent Initialization should come before everything else, and the Configuration tag before any Event tags.
- For each event, click it in the list on the left and check that the variable values are correct and that the status shows Tags Fired, not Tags Not Fired.
- Open GA4's real-time view (DebugView) and confirm the events are actually arriving with all their parameters.
Only once every key event shows green in both views should you click Submit and then Publish. If a critical error shows up after publishing, you can roll back to the previous published version in one click, through Versions, by selecting the older version and republishing it.
The most common mistakes and how to fix them
Duplicate events are the most common issue you'll notice in GA4 reports, showing up as double-counted conversions. It's almost always the same tag firing twice, often because the same event is set up both in GTM and manually in the site's code.
- Check whether you have the same Event Name set up in two places (GTM and gtag.js on the site) and remove the duplicate.
- If ecommerce data is missing, first check in Preview mode whether
dataLayer.pusheven sends theitemsarray before the GA4 tag fires. - Blocked tags are often the result of extra exception triggers on Google tags. Remove them and let Consent Mode handle the logic itself.
- Also check that your CMP consistently sends a
consent updateevent with every change, not just on the first page load.
Pro tip: If events are only missing on a user's first visit, the cause is almost always loading order: the CMP is loading too slowly relative to the Consent Initialization trigger. Check both load times in the Network tab, and if needed, load the CMP synchronously instead of asynchronously.
When to leave GTM setup to experienced hands
This guide covers a basic-to-intermediate setup that any digital marketer can pull off with a bit of patience. But some situations go beyond a DIY fix, and that's where the difference between a quick patch and a lasting solution shows.
Commissioning implementation makes sense for:
- a complex online store with multiple currencies, languages, or country-specific branches;
- a server-side GTM setup, which requires a separate server and coordination across multiple advertising platforms;
- integrations with external systems like a CRM, ERP, or payment providers, where an incorrect dataLayer directly affects business decisions.
A good approach to website development often integrates GTM and GA4 during the build itself, not as a fix tacked on at the end. The code is often structured precisely for the individual project, which allows for flexibility without unnecessary constraints. For further reading on related topics, there's also a guide to online advertising, explaining how GTM data feeds Google Ads campaigns.
For businesses just planning a site redesign or a new store and wanting analytics set up correctly from day one, an overview of the current offering is available at Moxy-web.
What actually matters in a GTM setup
Most Google Tag Manager guides focus on clicking through the interface: where to create a tag, where to type in the event name. That's the easy part.
Conventional advice often recommends adding extra consent conditions to every single tag "just to be safe." That's the wrong approach. Google tags already have consent logic built in, and adding manual conditions on top often just breaks the automatic adjustment that would otherwise work fine on its own.
What actually matters first isn't more tags or more triggers — it's discipline in naming your events, and a single Consent Initialization trigger set up correctly from day one. Everything else, including complex ecommerce tracking, is far easier to build on a solid foundation than to fix on a shaky one.
— Ziga
Sources
For a deeper look at individual steps, Google's own resources are useful: creating an account and container, Consent Mode support in GTM, how Consent Mode works, and setting up ecommerce events in GA4. For a broader look at analytics, the web analytics guide is also useful, helping set sensible KPIs around this data, along with a technical overview of tracking LLM traffic in GA4, useful for those who already know the basics and are looking for more advanced measurement scenarios.
- Create an account and container - Tag Manager Help
Frequently asked questions
What is Google Tag Manager, and why do I need it?
Google Tag Manager is a tool for managing tags on a website without directly touching the code. It lets you quickly add and change tracking tags for GA4, Google Ads, and other tools, without needing a developer every time.
How do I connect GTM to GA4?
You establish the connection with a GA4 Configuration tag, where you enter your GA4 property's Measurement ID. This tag fires on every page and sets the foundation that every subsequent Event tag builds on.
What is a Consent Initialization trigger, and why does it matter?
The Consent Initialization trigger ensures the default consent state is set before any other tags in the container fire. Without it, you risk GA4 or Google Ads tags firing before the user's consent state is even known.
Why are events in GA4 getting duplicated?
Duplication most often happens because the same event is set up both in GTM and manually in the site's code via gtag.js. The fix is to check both locations and remove the duplicate source.
How do I check that GTM is working correctly before publishing changes?
Use Preview mode (Tag Assistant), which shows the firing order of tags, variable values, and the status of sent events. Only once every key event is confirmed as successfully fired should you publish the changes by clicking Publish.
Recommended