How to Install Web Analytics Without Google Tag Manager
A direct script tag vs GTM: when you don't need a tag manager, how to add analytics in one line, and what you lose without GTM.
Most tutorials tell you to install web analytics through Google Tag Manager. But GTM is a 35 KB script loader that itself requires a consent banner in the EU (it loads third-party scripts that can set cookies). For privacy-first analytics, you often don't need it.
What GTM actually does
Google Tag Manager is a container: it loads other scripts based on rules you configure. It's useful when you have five different marketing tools, A/B testing, chat widgets, and a data layer — because GTM lets you manage them without a developer every time.
But if you're installing a single analytics script that doesn't use cookies, GTM adds complexity without benefit:
- Extra load: GTM's container script is ~35 KB. Then it loads your analytics script. Two round trips instead of one.
- Consent complexity: GTM itself is classified as a third-party tool. In the EU, even loading GTM may require user consent (depending on which tags fire before consent).
- Debugging layers: When something breaks, is it your tag, your trigger, or GTM itself?
Direct installation: one script tag
Privacy-first analytics like Gauss is installed with a single line in your HTML <head>:
<script defer src="https://cdn.gausslab.io/g.js" data-site-id="YOUR_SITE_ID"></script>That's it. No data layer, no trigger configuration, no GTM account. The script is small (~4 KB), loads with defer so it doesn't block rendering, and starts tracking page views automatically.
When you do need GTM
GTM makes sense when:
- You have multiple marketing tools (Meta Pixel, Google Ads, Intercom, etc.) that need to fire based on complex rules.
- Your marketing team updates tags without developer access.
- You need a consent management platform (CMP) to gate which tags fire.
If that describes you, you can still use Gauss inside GTM — add it as a Custom HTML tag. But you'll need to manage the consent logic for GTM itself.
WordPress, Shopify, Webflow
Most CMS platforms have plugin-based installation:
WordPress: Add the script to your theme's header.php, or use a plugin like "Insert Headers and Footers". Avoid analytics-specific plugins that often bundle their own tracking or add admin-side JavaScript.
Shopify: Go to Online Store → Themes → Edit code → theme.liquid. Add the script just before </head>.
Webflow: Project Settings → Custom Code → Head Code. Paste the script tag there.
Next.js / React: Use <Script strategy="afterInteractive"> from next/script, or add to your root layout:
<Script
src="https://cdn.gausslab.io/g.js"
data-site-id="YOUR_SITE_ID"
strategy="afterInteractive"
/>Single-page applications
For SPAs (React, Vue, Svelte), the script auto-detects client-side navigation if your app uses the History API (pushState). Most modern routers (React Router, Vue Router, Next.js App Router) do — so page views fire on route change without extra code.
If your router uses hash-based navigation or replaces history.state in an unusual way, you can fire manual page views:
gauss('pageview', { url: location.pathname });Does removing GTM break anything?
If GTM is your only tag container and you're replacing it with a direct analytics script, you just need to check two things:
Other tags: If GTM also fires your Facebook Pixel, LinkedIn Insight Tag, etc. — those still need a home. Migrate them to direct script tags in your
<head>or keep a "marketing GTM" separate from your analytics.Data layer events: If you're pushing custom events to
dataLayerfor GTM to pick up, you'll need to replace those with the analytics tool's own event API. For Gauss:gauss('event', 'purchase', { value: 99, currency: 'EUR' }).
Speed difference
A direct script vs GTM-loaded script isn't just about file size. GTM parses its container (a JSON blob of all your tags and triggers), then decides what to load. On a fast connection this is milliseconds. On mobile 3G it's measurable.
Google's own PageSpeed Insights flags GTM under "Reduce the impact of third-party code" when it's loaded synchronously — which it isn't by default, but many implementations add it to <head> without async.
The direct approach: one small script, loaded with defer, parsed once. No container logic overhead.
Summary
You don't need GTM to install privacy-first analytics. A single <script defer> tag is faster, simpler, and avoids GTM's own consent complications in the EU. Keep GTM for marketing tool management — not for analytics that was already easy to install directly.