Skip to content
Sultan Kautsar

Home / Notes /

How This Site Is Tracked

I set up measurement and consent for other people's websites, so this one should hold up to the same scrutiny. Here is everything it does, from the moment the page starts loading to the events GA4 receives, and how you can check it yourself.

The short version: a small consent banner I wrote myself, Consent Mode V2 in advanced mode, one Google Tag Manager container, four events in Google Analytics 4, and a Content Security Policy that only lets Google's tag domains in.

The Setup

The site is plain HTML, CSS and JavaScript on Cloudflare Pages. There is no framework, no consent platform and no tracking plugin. Everything that touches measurement lives in two files:

  • consent.js runs first, in the page's <head>. It sets the consent defaults, applies a stored choice, and loads Google Tag Manager.
  • main.js runs after the page is parsed. It draws the banner and pushes the events.
consent.js sets every Google signal to denied
   ↓
A stored choice, if there is one, updates the signals
   ↓
Google Tag Manager loads and fires the GA4 tag
   ↓
main.js shows the banner, or pushes events as you browse
   ↓
GA4 stores what your consent allows

The order is what makes Consent Mode work. consent.js is loaded without defer, so it runs before anything else can, and its first job is the default state:

Signal Default
analytics_storage Denied
ad_storage Denied
ad_user_data Denied
ad_personalization Denied

It also sets wait_for_update to 500 ms and turns on ad data redaction. If you chose before, your choice is read from local storage and applied immediately, so a returning visitor never has a page view sent with the wrong state.

This is advanced mode: Google Tag Manager always loads, and until you allow analytics, GA4 sends cookieless pings without identifiers. That keeps an aggregate picture of traffic without storing anything on your device. Basic mode, which blocks Google entirely until consent, is the stricter choice, and the right one for sites that handle sensitive data, like the dental practice I set up tracking for.

The Banner

The banner is about 60 lines of JavaScript and some CSS in the site's own design. Building it myself kept the page free of third-party scripts and let me get the details right:

  • Reject is as easy as accept: both buttons sit side by side with the same weight, which is what European regulators expect.
  • Two separate choices: analytics and advertising can be allowed independently under Customize.
  • A real update: every choice sends a Consent Mode update and a consent_update event the moment you click, not on the next page.
  • Withdrawal cleans up: turning analytics off deletes the _ga cookies already set, instead of leaving them behind.
  • Always reachable: Cookie settings in the footer reopens the banner on every page.
  • A limited lifetime: the choice expires after 12 months, and the banner asks again.

The Events

Page views alone don't say whether the site does its job, which is helping people decide to work with me. So the site pushes four events to the data layer, each tied to a question I actually want answered:

Event When it fires Parameters
cta_click A main call-to-action button is clicked cta_text, link_url
email_click An email link is clicked link_text
contact_submit The contact form is sent successfully None
case_study_read The last section of a case study scrolls into view, once per page case_study

The names are generic and use the snake case GA4 expects. Google Tag Manager picks each one up with a custom event trigger and forwards it to GA4. contact_submit and email_click are the ones that count as key events, since they are the closest thing this site has to a lead.

A case study counts as read when its final section reaches the screen, not when someone scrolls 90% of an arbitrary page. That makes the number comparable between short and long case studies.

What I Leave Out

What a setup refuses to collect matters as much as what it collects.

  • Nothing from the contact form: contact_submit carries no name, email address or message. The message goes from a Cloudflare function straight to my inbox and never touches the data layer.
  • No advertising tags: the site doesn't run Google Ads or any other pixel. The advertising choice exists so the four Consent Mode signals are always set correctly.
  • No test traffic: Google Tag Manager only loads on sultankautsar.com, so local previews and staging deployments never reach GA4. The consent banner and the data layer still work there, which keeps them easy to test. My own visits on the live site carry traffic_type: internal, which a GA4 data filter removes from reports.
  • No third-party embeds: fonts, images and the video are served from the same domain, so no other company learns about your visit.

Security Headers

Tracking scripts are code from someone else running on your page, so the site limits what they can do with a Content Security Policy, set in Cloudflare's _headers file:

  • Scripts may come only from this site and Google Tag Manager.
  • Data may be sent only to this site and Google's analytics and tag domains.
  • Styles, fonts and media may come only from this site.
  • Framing is blocked entirely, and forms may only submit to this site.

If a tag ever tried to load a script from anywhere else, the browser would refuse it. The same file adds HSTS, X-Content-Type-Options, a strict referrer policy and a Permissions Policy that turns off the camera, microphone and location.

Check It Yourself

None of this has to be taken on trust. Open your browser's developer tools on this page:

  1. In the Console, type dataLayer to see the consent default, any update, and every event pushed so far.
  2. In the Network tab, filter for collect. Before you choose, the gcs parameter reads G100, meaning everything is denied. After accepting all, it reads G111.
  3. In Application, look at local storage for the consent key, and at cookies for _ga, which only appears once you allow analytics.
  4. In the response headers of the page itself, read the Content-Security-Policy.

The privacy policy covers the same setup in legal terms. If you want your own site to hold up to this kind of inspection, get in touch.

Related notes

  1. Consent Mode V2
  2. Google Tag Manager
  3. Google Analytics 4

All notes →