Skip to content
Pierre Bossetti

gtag.js

GA4 & Looker Studio Dashboards

GA4 is too complex and you can't find your real CAC or ROAS? I clean up the tracking debt, build native events, and ship Looker Studio dashboards made for quick decisions.

GA4 paralysis and zombie events

GA4 is a raw data warehouse. It stores everything. It is not built for daily decisions. Open it and you face hundreds of reports, and still can't answer a simple question: what does a new customer cost me?

The mess often comes from the past. Previous agencies left tracking debt behind:

  • Zombie events. Events nobody uses, nobody owns, and nobody dares to delete.
  • Redundant GTM tags. Two or three tags fire for the same action. Conversions get counted twice, and your numbers look better than they are.
  • A slow main thread. Every extra tag runs JavaScript in the visitor's browser. That hurts your INP score and makes the site feel slow.

My answer: strategy before code. I start with a ruthless audit. I delete the debt. Then, with you, I define a short list of strict business KPIs. Only after that do I write new tracking code. If an event does not serve a KPI, it does not ship.

Native engineering vs. fragile DOM scraping

Most GTM setups track the page by scraping it. A marketer picks a CSS class and fires a tag when someone clicks it. It works on day one. Then a developer updates the design, the class changes, and tracking breaks. Nobody gets an error. The numbers just fall.

Scraping also counts false positives. A visitor clicks "Submit", the form returns an email validation error, and GTM still logs a lead. You pay to acquire leads that never existed.

The fix: events tied to real outcomes

I'm a full stack developer, so I fix this in the code. I send native gtag.jsevents from the application itself. They don't depend on the UI. A redesign can't break them. And they fire only when the backend confirms success with an HTTP response.

Here is a lead event that fires only after the server says yes:

async function submitLeadForm(formElement) {
  const formData = new FormData(formElement);
  try {
    const response = await fetch('/api/v1/leads', { method: 'POST', body: formData });
    if (!response.ok) throw new Error('API Error');

    const payload = await response.json();
    if (typeof window.gtag === 'function') {
      window.gtag('event', 'generate_lead', {
        form_id: formElement.id,
        lead_type: payload.lead_tier,
        value: payload.estimated_value
      });
    }
  } catch (error) {
    console.error('Lead submission failed');
  }
}

Read it from the top. The form data goes to the API. If the response is not OK, the code throws and no event is sent. If it is OK, the event carries real values from the server: the lead tier and the estimated value. Thetypeof window.gtag check keeps the page safe when a visitor refuses consent or an ad-blocker removes the script. No lead, no event. Clean data in, clean decisions out.

Bypassing GA4 quotas with BigQuery

Connecting Looker Studio straight to GA4 looks easy. It is a trap. Two limits will hurt you:

  • API quotas. GA4 caps how many requests it accepts. When several people open the dashboard at once, it crashes with "Exhausted concurrent requests". The meeting starts and the charts are empty.
  • Data retention. GA4 deletes detailed event data after 14 months. You can't compare this year with two years ago.

The fix is architecture. I export your raw GA4 data to Google BigQuery first. Then I connect Looker Studio to clean SQL tables, not to the GA4 API. The result: dashboards that load instantly, however many people open them, and history you keep forever.

The executive Looker Studio dashboard

Executives don't need 50 pie charts. Too many numbers slow decisions down. I design each dashboard to answer one question in under a minute: is the business healthy, and where should the next euro go?

I use a strict visual hierarchy, from top to bottom:

  • Top row: macro KPIs. Net revenue and blended CAC, each compared with last year. You see the health of the business at a glance.
  • Middle row: channel efficiency. Spend, ROAS and CAC by channel. You see what to scale and what to cut.
  • Bottom row: operational diagnostics. Funnel steps, landing pages and data-quality checks. Your team digs in here when a top number moves.

One screen. Few numbers. Each one tied to a decision. You stop interpreting data and start acting on it.