How I Set Up Tracking on 4 Websites Without Opening Google Tag Manager
I set up full tracking on 4 websites without opening Google Tag Manager once.
GA4 properties. Custom events. Cookie consent. CSP headers. Verified in Realtime. All from the terminal.
The sites: stratega.co, academy.stratega.co, trendjourney.ai. Different stacks, different needs, same method.
But the implementation was the easy part. What took actual thinking was deciding what to track and how — before writing a single line of code.
This guide covers both: the tracking strategy that should come first, and the implementation that follows.
Why most founders skip tracking
Everyone knows tracking matters. Nobody does it at launch.
The reasons are always the same: GTM’s interface is confusing, you’re not sure what to track, and “I’ll set it up after launch” turns into never.
Then three months later you’re staring at a blank analytics dashboard wondering where your leads come from.
The fix isn’t a better GTM tutorial. It’s starting from the right place.
Part 1: The tracking strategy
This is the part most guides skip. They jump straight to “create a GTM container” without asking what you’re trying to learn.
Start with questions, not tools
Before I touch any code, I sit down with one question:
“What do I need to know in 3 months that I don’t know today?”
This sounds obvious. It’s not. Most people start with “I should add Google Analytics” and end up with page views they never look at.
Here’s how this played out across my 4 sites:
stratega.co (marketing site + blog):
- Where do leads come from? → UTM tracking
- Which pages convert? → Form submission events
- Is the blog driving traffic? → Page views by section
- Are partners sending traffic? → UTM source by partner name
academy.stratega.co (learning platform):
- Are students coming back? →
login_page_view - Which modules do they complete? →
module_viewwith completion status - Where do they drop off? →
dashboard_viewwith progress data
trendjourney.ai (B2B fashion):
- Is the site getting traction? → Page views, session duration
- Who’s filling out the contact form? → Form submission events
- Which country? → GA4 geo data
Each site has different questions. Different questions mean different events. Different events mean different implementations.
Map questions to events
Once you have your questions, turn them into a tracking plan. Here’s the format I use:
| Question | Event | Type | Parameters |
|---|---|---|---|
| Are people finding my site? | page_view | Automatic | — |
| Are they requesting a quote? | form_submission | Custom | form_name |
| Are they logging into the course? | login_page_view | Custom | — |
| Which modules do students finish? | module_view | Custom | module_order, module_title, completed |
| Where do leads come from? | UTM tracking | Automatic | source, medium, campaign |
No question, no event. I don’t track things “just in case.” Every event answers a specific question I’ll actually look at.
Choose your tools — progressively
This is where most guides get it backwards. They tell you to set up GTM, GA4, a CRM pixel, a heatmap tool, and a privacy stack all at once.
Don’t.
Start with GA4 direct. One script tag, automatic page views, done. This covers 80% of what you need for a new site.
Add GTM when you need a second tool. The moment you add HubSpot tracking, or Facebook Pixel, or Leadinfo — that’s when GTM earns its place. GTM is a container that loads other scripts. If you only have one script, the container is overhead.
Add privacy/consent when you add cookies. GA4 alone with anonymized IPs doesn’t strictly require a cookie banner in many jurisdictions. But the moment you add a marketing pixel that drops cookies, you need consent management.
Add custom events when you have real questions. Don’t define 20 custom events on day one. Wait until you actually need to know something that page views don’t tell you.
Here’s how my stack evolved on stratega.co:
| Stage | What I added | Why |
|---|---|---|
| Launch | GA4 direct | Basic traffic data |
| Month 1 | GTM + Iubenda | Added HubSpot tracking, needed cookie consent |
| Month 2 | Leadinfo + Facebook Pixel | Lead identification, retargeting |
| Month 3 | Custom events + UTM convention | Needed to know which content converts |
| Month 4 | Delayed loading + CSP headers | Performance was suffering from script cascade |
Each addition solved a real problem I was having, not a hypothetical one.
Part 2: Implementation with Claude Code
Once you know what to track and which tools you need, the implementation is mechanical. This is where Claude Code turns a multi-hour job into one session.
How skills work
Claude Code has access to your entire project. When I say “add GA4 to the Academy,” it doesn’t just generate a snippet — it:
- Reads your project structure — finds the layout files, understands whether you’re using Astro, Next.js, plain HTML
- Checks what’s already there — sees if you already have a GTM container, existing scripts, a CSP header
- Generates code that fits — the snippet goes in the right file, in the right position, with the right framework syntax
- Handles the cascade — if adding GTM, it checks your CSP and updates it; if adding Iubenda, it places the config before the consent script
The key insight: describe the goal, not the implementation. Don’t tell Claude Code “insert this script tag on line 47.” Tell it “I want to track form submissions on my marketing site with GA4.” It figures out the how.
GA4 direct — The simplest setup
For new sites or apps with no third-party tools, GA4 direct is all you need:
<!-- GA4 direct — no tag manager needed -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXXX"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-XXXXXXXXX', { send_page_view: true });
</script>
Two script tags in your <head>. Automatic page views. No container, no third-party scripts loading behind your back.
This is what I use on the Academy. It’s also how I’d start any new site today.
GTM with delayed loading — When you outgrow GA4 alone
stratega.co runs GTM because it needs to load 4 tools: GA4, HubSpot, Leadinfo, and Facebook Pixel. GTM loads them all from one container.
But GTM has a cost: it’s a script that loads other scripts that load other scripts. One GTM tag becomes a cascade of 8+ network requests. Your page slows down.
The fix: delayed loading. The container doesn’t fire on page load — it waits for the first user interaction or 3 seconds.
// GTM delayed load — fires on first interaction or after 3s
var gtmLoaded = false;
function loadGTM() {
if (gtmLoaded) return;
gtmLoaded = true;
// ... standard GTM snippet for GTM-XXXXXXX
}
['mousemove','scroll','keydown','click','touchstart'].forEach(function(e){
document.addEventListener(e, loadGTM, {once:true, passive:true});
});
setTimeout(loadGTM, 3000);
Your page renders first. Tracking catches up silently. Users see a fast page. Analytics still gets all the data.
The tradeoff: your Content Security Policy needs to whitelist every domain in the cascade. My CSP for stratega.co includes googletagmanager.com, hs-scripts.com, hsforms.com, hscollectedforms.net, leadinfo.net, facebook.net, and more. Each third-party tool you add means another domain in your CSP. Claude Code handles this — it reads your _headers file and adds the domains automatically.
Custom events — Track what matters
Custom events are where tracking gets useful. Page views tell you someone visited. Custom events tell you what they did.
Here’s the real implementation from the Academy:
// Track which modules students view
gtag('event', 'module_view', {
module_order: moduleOrder,
course_slug: courseSlug,
module_title: moduleTitle,
module_completed: isCompleted
});
// Track dashboard engagement
gtag('event', 'dashboard_view', {
courses_enrolled: enrolledCount,
modules_completed: completedCount,
total_modules: totalCount
});
Three custom events total: login_page_view, dashboard_view, module_view. Each with parameters that answer a real question.
The important thing: I didn’t define these events at launch. I added them in month 3, when I actually needed to know which modules students were finishing. Start simple, add events when you have real questions.
The privacy stack
Every site runs Iubenda for cookie consent. Country auto-detection, GDPR-compliant banner, per-purpose consent.
But here’s the decision tree I use:
GA4 only, no marketing pixels? → You might not need a cookie banner (GA4 with anonymized IPs is analytics-only). Check your jurisdiction.
GA4 + one marketing tool (HubSpot, Facebook)? → You need consent. Add Iubenda or equivalent. Block the marketing pixel until consent is given.
Multiple tools through GTM? → Consent must fire before GTM loads. Iubenda’s blocking mode prevents GTM from loading marketing tags until the user accepts.
On the Academy, I run GA4 direct with no Iubenda — it’s an authenticated app with no ads and no marketing pixels. On stratega.co, Iubenda loads first and controls what GTM is allowed to fire.
The time GTM broke my login page
This is the story that taught me the progressive approach matters.
I set up the Academy with the same GTM container as stratega.co. Same delayed loading, same setup. Page views worked perfectly.
Then I noticed something strange in HubSpot. Every student login was showing up as a “lead.” HubSpot’s Collected Forms feature — loaded silently through GTM — was intercepting the login form submission and capturing it as a form fill.
Students logging into their course were being added to my CRM as prospects. The login form was also fighting with Cloudflare Turnstile (my CAPTCHA). GTM was breaking authentication.
The fix: I removed GTM from the Academy entirely. Switched to GA4 direct. Added only the custom events I actually needed.
The lesson: don’t copy your tracking setup between sites. Each site has different needs. A marketing site with HubSpot and Facebook Pixel needs GTM. A learning platform with login forms needs GA4 direct and nothing else.
If I had followed the progressive approach from the start — GA4 first, add tools only when needed — I would have never loaded GTM on the Academy in the first place.
Part 3: Verification
Tracking that isn’t verified isn’t tracking. It’s hope.
GA4 Realtime
Every time I deploy tracking, same process:
- Open GA4 → Reports → Realtime
- Visit the site in a new tab (incognito if you have ad blockers)
- Confirm page view appears within 30 seconds
- Trigger a custom event (submit a form, view a module)
- Confirm the event + parameters show up
If it’s not in Realtime, it’s not working. Don’t wait for the next-day report.
DebugView for custom events
GA4’s DebugView gives you the full parameter breakdown in real time. Every module_view with its module_order, course_slug, and module_completed — visible as it fires.
To enable it: add debug_mode: true to your gtag config during testing. Remove it before going live.
gtag('config', 'G-XXXXXXXXX', {
send_page_view: true,
debug_mode: true // remove after verification
});
Test forms and login flows
Any form on your site can be intercepted by third-party scripts loaded through GTM. If you have authentication, test the full flow with tracking active:
- Load the login page
- Open browser DevTools → Network tab
- Submit the form
- Check: did any unexpected requests fire? Is HubSpot, Facebook, or another tool capturing the form data?
This is how I caught the Academy bug. The Network tab showed HubSpot’s Collected Forms making a request on every login submission.
Part 4: Adding tools over time
Your tracking setup isn’t a one-time project. It grows with your business. Here’s the playbook for adding tools without breaking what already works.
When to add a new tool
Add a tool when you can answer “yes” to both:
- I have a specific question this tool will answer
- I’ll actually look at the data at least weekly
If you can’t answer both, don’t add the tool. You’ll forget it’s there, it’ll slow your site, and you’ll pay for something you never use.
How to add it safely
- Check compatibility first — Will the new tool conflict with existing scripts? Does it need GTM or can it run standalone?
- Update your tracking plan — Add the new events/data to your question → event map
- Add through GTM if you have it — One container, one place to manage everything
- Update CSP if needed — New tool = new domains to whitelist
- Verify in Realtime — Same process, every time
- Test login and form flows — New scripts can intercept forms you didn’t expect
The Claude Code workflow for adding tools
This is where the terminal workflow shines. Adding a tool to an existing setup:
I want to add Leadinfo (visitor identification) to my site.
I already have GTM with delayed loading. Container: GTM-XXXXXXX.
Add Leadinfo through GTM — create a custom HTML tag that loads
the Leadinfo script, triggered on All Pages.
Check my CSP headers and add leadinfo.net and leadinfo.com
to script-src, connect-src, and img-src.
Don't touch my existing GA4 or HubSpot setup.
Claude Code reads your existing configuration, adds the new tool without disrupting what’s already working, and updates the security headers. One prompt, one session.
Build it with Claude — prompts you can steal
Here are the exact prompts I’d use at each stage. Copy, paste, adapt to your stack. Each stage builds on the previous one — you don’t need to do them all at once.
The pattern is always the same: describe what you want to achieve, not how to do it. Let the agent read your existing setup and figure out where the new code goes.
Four sites. Four different tracking strategies. Four different implementations.
The one where I removed tracking taught me the most: start simple, add tools when you have real questions, and never assume what worked on one site will work on another.
Add Google Analytics 4 to my site. Measurement ID: G-XXXXXXXXX. Insert the gtag.js snippet in the main layout file's <head>. Use send_page_view: true for automatic page tracking. Add a custom event for form submissions — fire 'form_submit' with form_name parameter when any form with data-track is submitted. Verify: tell me how to check it works in GA4 Realtime.
I currently have GA4 direct on my site. I'm adding HubSpot tracking and need to move to GTM. Replace the GA4 direct snippet with Google Tag Manager. Container ID: GTM-XXXXXXX. Use delayed loading (first interaction or 3 seconds). Move GA4 into the GTM container — keep the same Measurement ID. Add the HubSpot tracking script through GTM as well. Include the noscript fallback in the <body>. Update my Content Security Policy headers for both GTM and HubSpot. Keep my existing custom events working.
I have a web app with login, dashboard, and content pages. Add GA4 custom events (gtag direct, no GTM): 1. login_page_view — fires when the login page loads 2. dashboard_view — fires on dashboard with parameters: items_count (number of items the user has) 3. content_view — fires on content pages with parameters: content_id, content_title, content_completed (boolean) Insert the events in the correct page files. Show me how to verify each event in GA4 Realtime > Events.
Add Iubenda cookie consent to my site. Site ID: XXXXXXX. The consent banner must load BEFORE Google Tag Manager. Configure it for EU country auto-detection, GDPR per-purpose consent. Block marketing cookies until the user accepts. Insert the configuration and scripts in the <head>, above the GTM snippet.