Skip to content

Add optional Microsoft Clarity heatmaps with privacy controls - #202

Merged
jimdc merged 3 commits into
mainfrom
integrate-microsoft-clarity-free-click-heatmap-a
Jul 31, 2026
Merged

Add optional Microsoft Clarity heatmaps with privacy controls#202
jimdc merged 3 commits into
mainfrom
integrate-microsoft-clarity-free-click-heatmap-a

Conversation

@jimdc

@jimdc jimdc commented Jul 30, 2026

Copy link
Copy Markdown
Collaborator

Summary

Adds an optional Microsoft Clarity integration for click and scroll heatmaps so the site owner can see which parts of the public UI are hard to use. The loader is dormant until a project id is configured — no live id is committed. When configured, Clarity loads asynchronously, fails soft if blocked, respects Do Not Track / Global Privacy Control, and masks form fields (including email) before any script runs.

Privacy posture (plain English)

CityScroll can load Microsoft Clarity to collect anonymous heatmaps of where people click and scroll, so hard-to-use parts of the site can be fixed. Form fields and typed text — including email — are masked and are not sent as plain text. Clarity does not load when a browser signals Do Not Track or Global Privacy Control, and the site works fully if Clarity is blocked or offline. Clarity is not used for advertising or personal profiles. First-party aggregate analytics and Cloudflare’s cookieless page-view totals remain separate.

Operator steps (project id)

Clarity requires a project under a Microsoft account. Until the id is set, the integration stays off.

  1. Sign in at https://clarity.microsoft.com/ with the site owner’s Microsoft account.
  2. Add a new project for cityscroll.org (and any live aliases you want measured).
  3. Open Settings → Setup and copy the project id (also visible in the project URL: https://clarity.microsoft.com/projects/view/<PROJECT_ID>/).
  4. Open Settings → Masking and set masking mode to Strict (entire page content masked; input content is always masked in every mode).
  5. Optional but recommended for a civic site: under Settings → Setup → Advanced, turn Cookies off until a consent flow exists. Multi-page session stitching is weaker without cookies; heatmaps still work.
  6. Enable the loader by one of:
    • Set CONFIGURED_PROJECT_ID in site/clarity.js to the real id and redeploy, or
    • Set window.CROL_CLARITY_PROJECT_ID = "<id>" in a small script before clarity.js, or
    • Add <meta name="crol-clarity-project-id" content="<id>"> on public pages.
  7. Confirm in the browser Network tab that https://www.clarity.ms/tag/<id> loads when DNT/GPC are off, and does not load when Do Not Track or Global Privacy Control is on.
  8. Spot-check a subscribe/feedback form: email fields carry data-clarity-mask="true".

What changed

  • site/clarity.js — config path, DNT/GPC skip, input masking, non-blocking tag inject
  • All public HTML pages load clarity.js after first-party analytics.js
  • Email fields on home subscribe and About feedback are masked in markup
  • About → Privacy copy updated in English and all ten shipping locales
  • SECURITY.md and AGENTS.md note the optional third-party script
  • Characterization: node --test test/clarity.test.mjs

Validation

  • node --test test/clarity.test.mjs — pass
  • python3 test/standards/i18n_keys.py — pass
  • python3 test/standards/i18n_fallback_sync.py — pass
  • reading-level ratchet — about.html improved vs baseline; suite pass

Status

dormant-until-configured — merge ships the wiring; live heatmaps begin only after the operator pastes a real project id and sets Strict masking.

@jimdc
jimdc force-pushed the integrate-microsoft-clarity-free-click-heatmap-a branch from f0c96be to 9c82366 Compare July 30, 2026 23:36
@jimdc
jimdc added this pull request to the merge queue Jul 31, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Jul 31, 2026
@jimdc
jimdc added this pull request to the merge queue Jul 31, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Jul 31, 2026
@jimdc
jimdc added this pull request to the merge queue Jul 31, 2026
jimdc added 2 commits July 30, 2026 20:57
Load Clarity only when a project id is configured. Skip on Do Not Track
and Global Privacy Control, mask form fields (including email), and
document the About privacy posture in all shipping languages. The
integration stays dormant until an operator adds a real project id.
The About privacy intro no longer claims a blanket "no cookies" once
optional heatmaps may load. Point the readiness gate at the non-exhaustive
accounts/ad-tech wording and the plain-language Clarity disclosure.
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Jul 31, 2026
Handlers re-fetch live data when generated_at is older than MAX_AGE_MS.
Fixed fixture timestamps (2026-07-29) aged out of that window and made
meeting-outcomes and property route tests hit real upstream data. Seed
fresh wall-clock timestamps so the routes serve the fixture writes.
@jimdc
jimdc force-pushed the integrate-microsoft-clarity-free-click-heatmap-a branch from 9c82366 to f027a07 Compare July 31, 2026 01:01
@jimdc
jimdc added this pull request to the merge queue Jul 31, 2026
Merged via the queue into main with commit 6e72a43 Jul 31, 2026
11 checks passed
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