Load TracerKit on the marketing site, with Fathom behind it - #88
Conversation
Analytics is mounted by (site)/layout.tsx and by nothing else. Not RootShell, which four roots share: docs/05 §4 says customer form traffic must never share a cookie domain with our analytics vendor, and a hosted form is somebody else's lead capture running on traffic they paid for. (app) is left out for a different reason — measuring what customers do inside their own account is a decision to take deliberately, not one to inherit from a marketing tag. No key, no script, no request, so a clone of this repo does not report to us. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The rule is easy to keep today and easy to break by accident later: one import moved into RootShell and every hosted form starts reporting to our vendor. That is the case the test simulates, and it turns four assertions red — the forms root among them — while the marketing control stays green. The control matters. "Not reachable" and "the walker resolved nothing" are the same green otherwise. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
The page said "This site runs no analytics" and its description promised "No analytics, no cookies". Shipping the Fathom tag without touching it would have made a published privacy policy false, on a product whose argument is that it does not quietly do things. The page had already committed to how this should go — "this page will change first and will name the specific tool" — so it names Fathom and TracerKit, and states the thing that actually distinguishes us: analytics does not run on a form we host for a customer, and a test fails the build if that stops being true. Cookieless is stated as checkable rather than as a promise, because it is: the delivered script never touches document.cookie. Its only browser storage is the blockFathomTracking opt-out flag, written only if you opt out. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
Blocker found in review, now fixed: the privacy page said the opposite.
The page had already pre-committed to the fix — "this page will change first and will name the specific tool" — so it now names Fathom and TracerKit, and states the thing that actually distinguishes us: analytics does not run on a form we host for a customer, with a test that fails the build if that stops being true. Cookieless is stated as checkable rather than as a claim, because it is: I grepped the delivered |
Fathom Analytics (
TLZGQNSJ) now reaches endpointforms.com through TracerKit.TracerKit side (already live, no deploy needed)
endpointforms.com, public keytk_yuaNQBLOVSHoaz1Qpageload, head, consent categoryanalyticsVerified at the layer that matters — the config a browser actually receives from
/api/c/<key>— rather than the API's echo of my own request: it carries the Fathom src,data-site: TLZGQNSJ, and SPA mode.It had to be an
inlinetag, notscript. TracerKit's loader sets onlyasyncandsrcon a script tag, and Fathom reads its site id only from adata-site/siteattribute — I checked the deliveredscript.js, and there is no query-string form. Ascripttag pointed at Fathom would have loaded and tracked nothing. See the note at the bottom.data-spa="auto"because the marketing site navigates client-side; without it only the first page of a visit is counted. The inline code guards against double injection, since the loader re-runs an inline tag per trigger.This repo
The loader is mounted by
(site)/layout.tsxand nothing else — deliberately notRootShell, which all four roots share.docs/05§4: customer form traffic must never share a cookie domain with our analytics vendor. A hosted form is somebody else's lead capture on traffic they paid for.(app)is excluded too, for a different reason: measuring what customers do inside their own account is a decision to take deliberately, not to inherit from a marketing tag.No key → no script → no request, so a clone of this repo does not report to us. The key is set on Vercel production only, so preview deployments do not pollute the stats.
The test, and why it has teeth
8 assertions walking the import graph. The realistic accident is not "someone adds analytics to the form" — it is someone moving the import into the shared shell. Simulating exactly that turns four red while the marketing control stays green:
/fstays green even under that simulation, because it builds its own document and never touches a layout — a side benefit of #56.npm run verifyexits 0.One thing worth knowing about TracerKit itself
Its tag model has no field for element attributes, so every vendor that identifies itself with a
data-*attribute has to be installed as inline — Fathom here, and by the look oftag-signatures.ts, Plausible and Umami too (Umami's own signature literally matches ondata-website-id). Inline tags also miss signature detection, which keys offsrcPattern, so this tag will not be recognised as Fathom in the dashboard. Not a blocker, and not this repo's problem — but it is a papercut in your product, worth an issue there.🤖 Generated with Claude Code