
Where does Google Tag Manager code go on a website?
Google Tag Manager code goes in two places on a website: the JavaScript snippet belongs as high as possible in <head>, and the noscript iframe belongs immediately after the opening <body> tag. Installing both snippets on every page lets the container load early and keeps fallback coverage available.
Google's Tag Manager setup docs say Tag Manager uses two snippets of code on each website page, then lets teams manage tags from the Tag Manager interface instead of changing website code for every tracking update (Google Tag Manager Help). That detail matters because many broken installs only include the head snippet.
At Virdis, we install GTM at the application shell or root layout level for custom SaaS sites, not one page at a time. We have used that template-level approach on analytics work around sites for Hona, Handoff, IndeHR, Torch Dental, MeterNet USA, and Aurora Lights. The install should be boring. The measurement plan is where the judgment belongs.
Use this placement table:
| Website type | Where to install GTM | What to check |
|---|---|---|
| Custom HTML site | Shared header and body partials | Every page includes both snippets |
| Next.js App Router | Root layout, with noscript near the opening body | Container does not duplicate on route changes |
| WordPress | Theme hook or trusted GTM plugin | Plugin is not also adding GA4 directly |
| Webflow | Project custom code settings | Code publishes to all relevant domains |
| Shopify | Theme layout or approved integration path | Checkout and consent behavior are handled correctly |
| HubSpot CMS | Global header/footer settings or template module | Existing HubSpot tracking is not duplicated |
Related Virdis resources: B2B SaaS web design, Sanity CMS development, website structure for SEO, and Next.js vs Webflow for SaaS.
What should you check before installing Google Tag Manager?
Before installing Google Tag Manager, audit the website for existing analytics, ad pixels, heatmaps, chat widgets, form scripts, and consent tools. The goal is to avoid duplicate GA4 page views, inflated conversions, unmanaged vendor scripts, privacy gaps, and a GTM container that inherits years of tracking debt.
Google's developer guidance recommends assessing existing tags before adding new ones and looking for code markers such as gtag(, googletagmanager.com, dataLayer, and product-specific scripts (Google for Developers). That audit step is not optional on a SaaS marketing site.
The research file for this post showed Virdis already has a small GTM audience: one related GA4 landing page had 7 sessions in the last 90 days, and another GTM placement page added 3 sessions. Search Console showed almost no non-branded traction, which means the opportunity is a sharper answer, not a rewrite of generic docs.
Run this pre-install checklist:
- Search page source for GTM-, gtag(, G-, AW-, fbq(, linkedinpartnerid, and hbspt.
- Check whether GA4 is already installed directly through gtag.js.
- List every marketing, analytics, chat, heatmap, and form script.
- Decide which tags should move into GTM and which should stay platform-native.
- Confirm who owns the GTM account, GA4 property, Google Ads account, and consent platform.
- Document conversion names before building triggers.
- Save a backup of the current layout or theme before editing shared templates.
We see the same failure pattern during redesigns: a team adds GTM, leaves a direct GA4 snippet in place, and then wonders why sessions or conversions look wrong. Fix the inventory first.
How do you create a Google Tag Manager web container?
Create a Google Tag Manager Web container by signing in to Tag Manager, creating an account for the company, creating one Web container for the website, accepting the terms, and copying the generated container ID. A normal marketing website needs one container, not one container per page.
Google lists Web as the container type for websites and web apps, with separate container options for iOS, Android, AMP, and Server containers (Google Tag Manager Help). For most seed to Series B SaaS websites, the right starting point is a client-side Web container. Server-side tagging can come later when measurement governance or performance justifies it.
Set it up this way:
- Go to https://tagmanager.google.com.
- Create or select the company account.
- Create a new container named after the top-level website domain.
- Choose Web as the target platform.
- Copy the container ID, which starts with GTM-.
- Store admin ownership in the team's shared documentation.
- Create a first workspace for the initial install.
For custom SaaS builds, we usually pair the GTM setup with a measurement plan: primary CTA clicks, form starts, form submissions, booked meetings, pricing-page interactions, and demo intent. That pairs well with a site architecture project because the pages and events should describe the same buyer journey.
The tradeoff is control. GTM makes tag changes faster, but it also lets non-developers ship JavaScript into production. Give marketers publishing access when the workflow needs it, but use approvals or version reviews when tags can affect performance, privacy, or revenue reporting.
How do you add Google Tag Manager to a custom-coded website?
Add Google Tag Manager to a custom-coded website by placing the head snippet in the global document head and the body snippet immediately after the opening body tag in the shared layout. Deploy once, then verify the container appears on every indexable route and does not duplicate during client-side navigation.
For a simple HTML site, the install looks like this with your real GTM-XXXXXXX ID:
html <!doctype html> <html lang="en"> <head> <!-- Google Tag Manager head snippet goes here --> </head> <body> <!-- Google Tag Manager noscript snippet goes here --> <main> Page content </main> </body> </html>
For a Next.js App Router site, put the script in the root layout and keep it tied to the global shell, not a page component that remounts during navigation. If the site already uses next/script, load GTM deliberately and keep the noscript fallback near the top of <body>.
Use this implementation sequence:
- Install the snippets in the global layout.
- Deploy to a preview environment first.
- View source and confirm one GTM- container ID appears.
- Open several routes and confirm no duplicate container loads.
- Test a route transition if the site is a single-page app.
- Publish the production deploy after GTM Preview connects.
We prefer this template-level install for Next.js vs WordPress for SaaS style projects because it keeps tracking independent from page authors. A content editor should not need to remember analytics code when publishing a new landing page.
Why should SPAs use data layer events instead of brittle click triggers?
Single-page apps should use window.dataLayer events for important conversions because data-layer pushes describe the business action directly, while click and visibility triggers depend on fragile DOM details. CTA labels, class names, modal behavior, and route transitions change often. A stable event contract survives redesigns.
Google's Tag Manager documentation describes the data layer as an object used to pass information to Tag Manager, then use that information in tags, triggers, and variables (Google Tag Manager Help). In practice, that means a form success state should push a clean event instead of relying on a button click.
A simple lead event can look like this:
js window.dataLayer = window.dataLayer || []; window.dataLayer.push({ event: "generatelead", formname: "demorequest", leadtype: "sales", pagepath: window.location.pathname });
This is especially useful on Next.js, React, Vue, and other SPA-style sites. Route changes may update the visible page without a full document reload, so page-view and conversion tracking need deliberate triggers. For critical events, we prefer pushing the event when the app knows the action succeeded: validated form submission, scheduler completion, account signup, or pricing CTA click.
Use click triggers for low-risk interactions. Use data-layer events for revenue reporting.
How do you add GA4 and conversion events inside GTM?
Add GA4 inside GTM by creating a Google tag or GA4 event tags in the container, setting the trigger to Initialization or All Pages where appropriate, then adding separate event tags for conversions such as form submissions, CTA clicks, and booked demos. Publish only after every event fires with expected parameters.
Google's Tag Manager setup guidance says the Google tag can use the Initialization - All pages trigger so it fires before other triggers, and it says data collection may take up to 30 minutes to start after setup (Google Tag Manager Help). That delay is normal. Broken triggers are not.
For a B2B SaaS marketing site, start with a small event model:
| Event | Trigger | Useful parameters |
|---|---|---|
| ctaclick | Click or data-layer event for primary CTA buttons | ctatext, pagepath, ctalocation |
| formstart | First interaction with a demo/contact form | formname, pagepath |
| generatelead | Validated successful form submission | formname, leadtype |
| bookdemo | Scheduler completion or thank-you view | scheduler, pagepath |
| pricingintent | Pricing CTA or pricing-page interaction | plan, ctatext |
Keep names stable. Changing event names every quarter makes year-over-year reporting messy and breaks paid-media optimization. We use naming conventions before we touch GTM, then match the events to the pages that matter: homepage, product pages, pricing, comparisons, case studies, and contact.
For related site planning, see Next.js vs Framer for SaaS, Next.js vs HubSpot CMS for SaaS, and Next.js vs Squarespace for SaaS.
How do you test Google Tag Manager before publishing?
Test Google Tag Manager before publishing by using Preview mode, opening the site through Tag Assistant, clicking through key pages, and confirming each tag fires only when its trigger conditions are met. Testing should include page loads, SPA route changes, form submissions, data-layer events, consent states, and production-domain behavior.
Google's Tag Assistant docs say Preview mode opens a debug window where you can inspect which tags fired, which tags did not fire, and what data was available for each event (Google Tag Manager Help). That visibility is the difference between a clean publish and a silent reporting bug.
Use this QA checklist:
- Click Preview in the GTM workspace.
- Connect the preview to the staging or production URL.
- Confirm the container connects on the homepage.
- Open core pages: homepage, pricing, contact, comparison, and one case study.
- Check that GA4 page views fire once per page view.
- Click primary CTAs and confirm event parameters are populated.
- Submit a test form and confirm the conversion event fires once.
- Trigger a data-layer event and confirm GTM reads the variables.
- Switch consent choices and confirm restricted tags respect the user's choice.
- Publish a named container version with release notes.
- Check GA4 DebugView and realtime reports after publishing.
This is where many teams skip too fast. A button-click trigger that works on the homepage may fail on a CMS-driven landing page because the component class changed. A form trigger may fire on validation errors instead of successful submissions. Test the money paths.
What breaks when GTM is installed wrong?
Wrong GTM installs break tracking by creating duplicate page views, missing conversions, blocked consent behavior, slow pages, and untrusted reporting. The most common causes are installing only one snippet, installing GTM more than once, leaving old analytics scripts in place, publishing untested tags, or tracking form attempts as leads.
Google's consent mode docs describe two consent implementations, basic and advanced, and say developers need to get the user's consent choice, communicate the consent state to Google, and ensure tags behave according to that choice (Google for Developers). That is a website implementation issue, not just an analytics setting.
Watch for these problems:
| Symptom | Likely cause | Fix |
|---|---|---|
| Page views doubled | Direct GA4 and GTM GA4 both installed | Remove one source of page-view tracking |
| No live data | Container not published or wrong environment | Publish the correct version and verify domain |
| Preview works, live does not | Consent, filters, or unpublished workspace | Test production with consent states |
| Leads inflated | Trigger fires on form click, not success | Fire on thank-you state or validated success event |
| Site feels slower | Too many third-party tags | Remove unused tags and delay nonessential scripts |
| Events missing on route changes | SPA navigation not tracked | Add history-change triggers or data-layer events |
On one SaaS tracking cleanup, we found three separate sources trying to report lead intent: a direct GA4 snippet, a GTM GA4 event, and a form tool integration. The fix was not more tagging. We removed duplicate sources, kept the validated form success event, and made the container version history readable enough for the marketing team to maintain.
The honest tradeoff: GTM reduces developer bottlenecks, but it can become a second production surface. Treat it like code. Use naming conventions, workspaces, version notes, review, and cleanup.
