Repository navigation
fix(consent): load Ketch first and hold Heap and GA4 until consent - #143
dg-coreylweathers wants to merge 2 commits into
Conversation
GregHolmes
left a comment
There was a problem hiding this comment.
Request changes
[S1] Consent gating has no checked-in behavioral regression test. The PR records manual Playwright results, but web/package.json has no test command and the repository has no test for Ketch, Heap, GA4, or the footer privacy control. A future vendor-script or tracker change can restore pre-consent requests without CI detecting it.
Add a browser test that stubs Ketch and verifies:
- Heap and GA4 do not load before consent, after rejection, or when Ketch is unavailable
- both load only after
targeted_advertisingis granted - withdrawal disables GA and calls Heap
stopTracking
Verified: the vendored Ketch and consent-banner files match the pinned deepgram-docs commit byte-for-byte; the live Ketch config classifies both trackers under targeted_advertising; and the full-repository Node 22 build and current CI checks pass.
Operational decision: merging updates staging only. web-production.yml deploys only from a root CLI release, so decide whether this privacy fix needs an expedited production release.
523a492 to
2c8443f
Compare
|
Thanks Greg, S1 is in.
On prod: merging only updates staging. Prod still loads Heap and gtag without Ketch today, and Known gap: |
|
Pushed two more fixes from a second look at this.
Checked in Chromium, Firefox and WebKit: zero heap/google requests before grant (blocked Ketch, rejected, and pre-grant), font requests only to the same origin, Inter renders, and grant loads Heap + gtag without a reload. One thing I'm not fixing here: the footer fallback in the vendored |
Load the vendored Ketch loader as the first script on cli.deepgram.com and gate Heap and GA4 on the targeted_advertising purpose. Nothing loads before consent, after rejection, or when Ketch is unavailable; granting loads both without a reload, and withdrawal disables GA4 and calls Heap stopTracking. Google Consent Mode defaults are queued as denied before gtag.js, updated to granted on consent and back to denied on withdrawal. web/tests/consent-gate.test.cjs runs the shipped ketch.js and trackers.js in node:vm against a fake Ketch, settling timers, intervals, promises and load events so delayed fail-opens are caught, and checks the vendored files against SOURCE.json. web-ci.yml runs npm ci, npm test and the build on PRs that touch web/.
The page preconnected to and loaded Google Fonts on every view, sending the visitor's IP to Google before consent. Inter (variable) and Fira Code are now served from @fontsource 5.3.0, the Google Fonts links are gone, and web/tests/build-output.test.cjs fails if a Google font host comes back.
280d557 to
5cd0725
Compare
What
cli.deepgram.com and cli.staging.deepgram.com load Heap and GA4 (G-TYPC1TBCKT) before any consent, including for visitors in GDPR regions and when Ketch is blocked, and have no Ketch and no privacy control. This brings the page in line with developers.deepgram.com:
web/src/consent/ketch.js: docs'fern/assets/ketch.js, copied verbatim (the Ketch loader fordeepgram_marketing_siteplus thedgOnConsent/dgOnRevokehelpers), inlined as the first script in<head>.web/public/consent/dg-consent.js: docs' built consent banner, unchanged. It mounts the footer "Your Privacy Choices" control into<div id="fern-footer">(the id the bundle looks for), and shows a Privacy Policy link instead when Ketch is unavailable. Source commit and hashes are inweb/src/consent/SOURCE.json.web/src/consent/trackers.js: Heap (docs' snippet, which also fixes the oldheap[o]=stub bug) and GA4 start only after Ketch grantstargeted_advertising, and stop if it's withdrawn (HeapstopTracking, GAga-disable-<id>, then the banner's reload on withdrawal). Neither starts if Ketch never loads.<html class="dark">makes the banner use its dark theme to match the site. The page has nodark:utilities, so nothing else changes.GA4 purpose:
targeted_advertising. The live Ketch config (production/gdpr/en/config.json) lists_gaand_ga_*, along with Heap's_hp2_*, undertargeted_advertising. Nothing related is listed underanalytics.Checked
Built with
npm ci && npm run build(node:22, Docker), serveddist/, then ran Playwright with a fresh profile each time and Ketch's location stubbed:<head>_gacookiesNotes
web-production.yml), so merging this updates staging only. cli.deepgram.com keeps the ungated trackers until the next release.Release plan
Merging to main only deploys staging. Production (
web-production) runs on a rootv*release, and prod still loads Heap and gtag without Ketch today. Plan: request a patch release right after merge, unless docs#1302 retires cli.deepgram.com first.Tests
web/tests/consent-gate.test.cjs(run by the newweb-ci.ymlon PRs touchingweb/**) covers: nothing loads before consent, after rejection, or with Ketch unavailable; Heap and GA4 load only ontargeted_advertising; withdrawal disables GA4 and calls HeapstopTracking.Known gap
_ga/_ga_*cookies persist after withdrawal until they expire. GA is disabled but the cookies are not deleted (same as developers.deepgram.com).Maintenance
web/src/consent/SOURCE.jsonpins the vendored Ketch files by sha256, and the test checks it. If cli rebrands, re-copy both files from the same docs commit and updateSOURCE.json, or the hash test will fail.