fix(site): make the analytics actually cookieless - #69
Merged
Conversation
The component claimed to set no cookies. It set two.
`client_storage: "none"` passed inside `gtag("config", ...)` is not a directive
gtag recognises. It forwarded it as a custom event parameter — every hit carried
`ep.client_storage=none` — and GA4 wrote `_ga` and `_ga_<id>` regardless. The
setting did nothing except add a meaningless field to the payload.
Consent Mode is the mechanism that works, declared before `js` and `config`:
gtag("consent", "default", {
analytics_storage: "denied",
ad_storage: "denied",
ad_user_data: "denied",
ad_personalization: "denied",
});
Measured in a real browser before and after, on the built output:
before document.cookie -> _ga_C1KM4SN3JR=GS2.1...; _ga=GA1.1...
payload -> ep.client_storage=none
after document.cookie -> (none)
payload -> gcs=G100 pscdl=denied
`gcs=G100` is GA acknowledging the denial. A page_view is still recorded (204),
title and location are still correct, and npa=1 still reports ad
personalisation off. The only thing that changed is that the claim is now true.
Worth recording why this survived review. Every earlier check tested the wrong
thing: grepping the built HTML for `client_storage: "none"` proved the string
was emitted, never that GA honoured it, and executing the script against a DOM
stub cannot observe cookies because the stub has no cookie jar. Both passed.
Only a real browser could see it.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
vishr
added a commit
that referenced
this pull request
Aug 18, 2026
fix(site): make the analytics actually cookieless
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The component claimed to set no cookies. It set two.
What was wrong
client_storage: "none"passed insidegtag("config", ...)is not a directive gtag recognises. It was forwarded as a custom event parameter — every hit carriedep.client_storage=none— and GA4 wrote_gaand_ga_<id>anyway.That invalidated the central claim of #66: "no
_gacookie, so the site needs no consent banner." It wrote_ga, and in the EU that needs consent.The fix
Consent Mode, declared before
jsandconfig:Measured in a real browser, before and after
document.cookie_ga,_ga_C1KM4SN3JR(none)gcs=G100ep.client_storage=nonepscdl=deniedpage_viewrecordednpa=1npa=1Only the cookies changed. Measurement still works.
Why it survived review
Every earlier check tested the wrong thing. Grepping the built HTML for
client_storage: "none"proved the string was emitted, never that GA honoured it. Executing the script against a DOM stub cannot observe cookies — the stub has no cookie jar. Both passed; both were worthless for this claim. Only a real browser could catch it.This is the second defect in this one file that passed verification while not doing what it said — the first shipped the whole IIFE inside a template literal, inert.
Note
google-analytics.com/g/collectfails withnet::ERR_SSL_PROTOCOL_ERRORon the machine this was tested from, both before and after the change. Thegoogle.com/g/collectfallback returns 204 so hits land. That looks like local TLS interception, not a site problem.