feat(app): add the Microsoft Clarity tag to the app shell - #53
Merged
Conversation
Adds Microsoft Clarity (session replay + heatmaps) to app.html, the entry
point for the authenticated SPA served at /app.
Not merged as-is on purpose — see the PR. Two things need a decision first:
1. src/pages/PrivacyPage.tsx says "No third-party tracking pixels or
marketing tags." Clarity is a third-party tag, so that line stops being
true the moment this ships.
2. app.html is the app shell, not a landing page. Session replay there can
record what the reader is actually reading — saved article and PDF
content, annotations, board contents, and chat questions — which is the
private material the product exists to keep private ("Research library:
capture, annotate, and AI-chat over your reading — private by default").
Whether Clarity's content masking is set to strict for this project
determines whether that happens, and that is a setting in the Clarity
dashboard, not in this repo. I cannot verify it from here.
Verified locally (Node 24.19.0):
pnpm format:check Checked 168 files in 37ms. No fixes applied.
pnpm lint Lint: 0 errors, 38 warnings across 194 files.
(unchanged from main — app.html is excluded from Biome
by "!**/*.html")
pnpm typecheck tsconfig.app.json + tsconfig.worker.json — clean
pnpm test Test Files 18 passed (18), Tests 97 passed (97)
pnpm build ✓ built in 474ms
the tag reaches the built shell:
dist/app.html 1 occurrence of clarity.ms/tag/y6budslpbi
The Clarity project id is a public client-side site key, not a secret.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ✅ Deployment successful! View logs |
reader | 6bb0b79 | Aug 22 2026, 11:00 PM |
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.
What this is
One line added to
app.html: the Microsoft Clarity tag (session replay + heatmaps).app.htmlis not a landing page. It is the Vite entry for the authenticated SPA that theworker serves at
/app(vite.config.ts→app: path.resolve(__dirname, 'app.html');src/worker.ts"Assets serves app.html at /app"). So this loads inside the reading andannotating surface, on every session.
1. It contradicts the privacy page.
src/pages/PrivacyPage.tsx, under "What we don't do":Clarity is a third-party tag. That line stops being true the moment this ships.
2. Session replay in the app shell can record the library itself. Clarity replays capture
DOM content unless masking is set to strict. The DOM here contains exactly what the product
promises to keep private, per its own privacy page and description:
your annotations")
The product is described as "Research library: capture, annotate, and AI-chat over your
reading — private by default." Recording replays of that is a different privacy posture, not
a metrics addition.
Masking is a Clarity dashboard setting, not a repo setting — I cannot verify it from here.
If masking is strict for project
y6budslpbi, this is much narrower than the above; if it isnot, replays of private reading material start accumulating on merge.
So there are two things only you can settle: whether masking is strict, and what
PrivacyPage.tsxshould say. I did not edit the privacy copy — that is a statement to yourusers about their own documents, not something to guess at in a PR that adds a script tag.
This PR is left open for that reason, not because anything failed. Merge does not deploy —
deploy.ymlisworkflow_dispatch:only — so there is no time pressure.For reference, the sibling
setlinerepo enforces the disclosure rule in CI ("the privacynotice discloses every third-party script the site loads").
readerhas no equivalent test,which is why nothing failed here.
Verification
The tag reaches the built shell rather than only the source:
I did not run the whole
pnpm qualitychain (it also builds the extension, runs docs checksand the CF build); CI runs it on this PR.
The Clarity project id is a public client-side site key, not a secret. Nothing else in the
diff; no
package.jsonchange.🤖 Generated with Claude Code