Spent a whole day debugging GA4? Here's the exact trail I followed to trace why events weren't reaching the dashboard.
😤 The Most Frustrating Debugging Session of My Week
I pushed events to Data layer. Console showed them perfectly. GA4 dashboard? Absolutely nothing. Classic.
This wasn't a side project — this was a client's production analytics setup. No senior to ask. So I went layer by layer and finally cracked it. Here's exactly what I found.
🔴 Problem 1: GTM Container ID Was Missing in .env
First thing I checked — Network tab, filtered by gtm.js. What I saw:
gtm.js?gtm_cookies_win=x → 400 Bad Request
Notice anything? No id=GTM-XXXXXXX in the URL. Google's server basically said — "Kaunsa container? ID hi nahi di!"
The .env file was missing GTM_CONTAINER_ID. App was calling GTM with a blank ID. Fix:
Code
Result → gtm.js 200 OK ✅
🍪 Problem 2: OneTrust Was Blocking GA4
GTM loaded but /g/collect still not appearing. Zero requests to GA4.
I noticed these in dataLayer:
OneTrustLoaded
OneTrustGroupsUpdated
onetrust_marketing_tag
OneTrust is a Cookie Consent Manager. It blocks all analytics tags until the user accepts cookies. I hadn't accepted the banner. Once I clicked "Accept All" — boom, /g/collect started firing! ✅
Lesson: Always accept cookies before testing GA4 in a consent-managed setup.
⚙️ Problem 3: GTM Triggers Not Configured for Custom Events
Page load events were going through. But my custom clickContent events? Still missing from GA4.
Here's the truth most developers don't know:
dataLayer.push() ≠ GA4 receives it.
GTM needs a Trigger to listen for your event and a Tag to send it to GA4.
For page_view — trigger existed ✅. For clickContent — no trigger, no GA4 call ❌.
What GTM needs for each custom event:
Data Layer Variable — for each parameter (id, name, type etc.)
Custom Event Trigger — Event Name: clickContent (exact match, case-sensitive!)
GA4 Event Tag — connected to that trigger
✅ Validation Checklist — Use This Every Time
window.dataLayer in console — event present with right name?
Network → gtm.js — 200 OK? If 400, Container ID missing in env
Cookie consent — clicked "Accept All"?
Network → /g/collect — GA4 receiving the hit?
GA4 → Reports → Realtime — data showing? (2–5 sec delay)
GA4 → Admin → DebugView — exact parameters per event
💡 Lessons Learned
1. dataLayer is not GA4. It's just a JavaScript array. GTM is the bridge. GA4 is the destination.
2. A developer's job ends at dataLayer.push(). Triggers, tags, publishing — that's the GTM Admin's job. Know your boundary.
3. Missing env variables are silent killers. No UI error — just a 400 in Network tab that most developers never check.
4. Cookie consent is a gate, not decoration. Analytics cannot fire without user permission in any consent-managed setup.
🎯 Conclusion
If your GA4 events aren't showing up, follow the chain — dataLayer → GTM → Cookie Consent → /g/collect → Dashboard — and the break will reveal itself.
Most of the time it's one of three things: missing Container ID, cookie consent blocking the tag, or a GTM trigger never created.
Push clean, well-named events to dataLayer, document them clearly, and hand it off to the Analytics team with confidence. Your job is done.
Continue Reading
I spent a week fixing broken models, PyTorch errors, and robotic voices — here's the stack that finally worked for free Hindi YouTube TTS.