feat(analytics): self-hosted Umami tracker on keepsimple.io - #176
Conversation
Cookieless Umami (analytics.administration.ae), domain-scoped to keepsimple.io + www so staging and preview traffic is not counted. Runs alongside Mixpanel; nothing removed. Also lands the font passport block in CLAUDE.md, which was live locally but never committed.
|
Claude finished @manager's task in 1m 15s —— View job Review: PR #176 — self-hosted Umami tracker
|
| {/* Umami, self-hosted, cookieless. data-domains keeps preview/staging traffic out. */} | ||
| <script | ||
| defer | ||
| src="https://analytics.administration.ae/script.js" |
There was a problem hiding this comment.
Security: third-party script domain doesn't match the "self-hosted" claim.
The PR description says this is a "self-hosted Umami tracker," but the script is loaded from analytics.administration.ae — a domain unrelated to keepsimple.io or any KeepSimple-owned infrastructure I can find in this repo. That's a meaningful discrepancy:
- This unconditionally injects third-party JS with full DOM/page access into
<Head>on every render (dev, staging, prod, preview) — unlike GA/Mixpanel, which are lazy-loaded and gated behindNEXT_PUBLIC_INDEXING(seesrc/pages/_app.tsx:48,147,236).data-domainsonly filters what Umami records; it does not stop the script from loading and executing on every deploy. - A compromised or unverified third-party origin serving
script.jshere can read cookies/localStorage, exfiltrate data, or modify the DOM — full script-injection blast radius. - If this is genuinely self-hosted, the script origin should be KeepSimple-owned infra (e.g.
analytics.keepsimple.io), not an unrelated third-party domain.
Please confirm analytics.administration.ae is an intentionally provisioned, trusted endpoint before merging. If it is, consider:
- Sourcing the URL/website-id from an env var (
NEXT_PUBLIC_UMAMI_*) rather than hardcoding, so staging/prod and endpoint rotation don't require code changes. - Adding
integrity(SRI) if the endpoint supports versioned/immutable script hashes, since this loads on every page unauthenticated.
The Umami script tag shipped in #176 is blocked by our own CSP: neither script-src nor connect-src allows analytics.administration.ae, so browsers refuse to load the tracker and to send events. Adds the host to both.
Adds our self-hosted, cookieless Umami tracker to keepsimple.io alongside Mixpanel. Nothing is removed.
_document.tsx, domain-scoped withdata-domainsso staging and preview traffic is not counted.CLAUDE.md, which was live in the working copy but never committed.Why: the current Mixpanel plan blocks API access (402 on every query endpoint), so no automation can read our own product numbers. Umami gives machine-readable data for free, and its self-hosted v3 covers funnels, retention, journeys and goals.
Merging this branch into
devbuilds the staging image; production only follows on a later merge tomain.🤖 Generated with Claude Code