Skip to content

Load TracerKit on the marketing site, with Fathom behind it - #88

Merged
coreyhaines31 merged 3 commits into
developmentfrom
feature/tracerkit-fathom-analytics
Sep 8, 2026
Merged

coreyhaines31 merged 3 commits into
developmentfrom
feature/tracerkit-fathom-analytics

Conversation

@coreyhaines31

Copy link
Copy Markdown
Owner

Fathom Analytics (TLZGQNSJ) now reaches endpointforms.com through TracerKit.

TracerKit side (already live, no deploy needed)

  • Site Endpoint Forms → endpointforms.com, public key tk_yuaNQBLOVSHoaz1Q
  • Tag Fathom Analytics, enabled, pageload, head, consent category analytics

Verified 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 inline tag, not script. TracerKit's loader sets only async and src on a script tag, and Fathom reads its site id only from a data-site/site attribute — I checked the delivered script.js, and there is no query-string form. A script tag 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.tsx and nothing else — deliberately not RootShell, 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:

PASS  the marketing root reaches the loader      <- control
FAIL  the hosted form's root does not
FAIL  nor does the signed-in app
FAIL  nor does the auth root
FAIL  and the shell four roots share does not reach it either

/f stays green even under that simulation, because it builds its own document and never touches a layout — a side benefit of #56.

npm run verify exits 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 of tag-signatures.ts, Plausible and Umami too (Umami's own signature literally matches on data-website-id). Inline tags also miss signature detection, which keys off srcPattern, 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

coreyhaines31 and others added 2 commits September 8, 2026 12:12
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>
@vercel

vercel Bot commented Sep 8, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
endpointforms Ready Ready Preview Sep 8, 2026 8:03pm UTC

Request Review

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>
@coreyhaines31

Copy link
Copy Markdown
Owner Author

Blocker found in review, now fixed: the privacy page said the opposite.

/privacy stated verbatim "This site runs no analytics. No Google Analytics, no Meta pixel…", and its meta description promised "No analytics, no cookies… Written specifically for what this site actually does." Merging as-is would have published a false privacy policy on a product whose whole argument is that it does not quietly do things.

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 script.js — document.cookie appears 0 times. Its only browser storage is blockFathomTracking, written only if a visitor opts out, so by default it stores nothing. The existing paragraph about local storage holding only the theme would otherwise have become incomplete.

@coreyhaines31
coreyhaines31 merged commit 928b6d9 into development Sep 8, 2026
3 checks passed
@coreyhaines31
coreyhaines31 deleted the feature/tracerkit-fathom-analytics branch September 8, 2026 21:07

This branch was successfully deployed

1 active deployment
Preview — 84abc629 Deployed Sep 8, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant