feat(analytics): load Umami heatmap recorder #77

Merged
tudor merged 1 commits from feat/umami-heatmap-recorder into main 2026-07-21 15:06:04 +00:00
Owner

Summary

Adds the Umami session recorder (recorder.js) that powers heatmaps, next to the existing analytics tracker in the root layout.

Notes

  • Loaded via next/script (strategy="afterInteractive"), matching the existing tracker rather than a bare <script defer>.
  • Carries the same data-domains guard as the main tracker (schoolcompare.co.uk,www.schoolcompare.co.uk) so it only fires on the production hostnames — staging runs the same image under a different host and must not pollute the heatmap/session data.
  • Cookieless: recorder.js uses Umami's server-side session model (no cookie or local storage written to the device), so it adds no new PECR cookie-consent trigger. (As discussed: cookieless ≠ automatically consent-free under GDPR — worth a line in the privacy policy, but no banner/cookie is required for this to run.)

Testing

  • tsc --noEmit and next build — clean.

🤖 Generated with Claude Code

https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB

## Summary Adds the Umami **session recorder** (`recorder.js`) that powers heatmaps, next to the existing analytics tracker in the root layout. ## Notes - Loaded via `next/script` (`strategy="afterInteractive"`), matching the existing tracker rather than a bare `<script defer>`. - Carries the **same `data-domains` guard** as the main tracker (`schoolcompare.co.uk,www.schoolcompare.co.uk`) so it only fires on the production hostnames — staging runs the same image under a different host and must not pollute the heatmap/session data. - **Cookieless:** `recorder.js` uses Umami's server-side session model (no cookie or local storage written to the device), so it adds no new PECR cookie-consent trigger. (As discussed: cookieless ≠ automatically consent-free under GDPR — worth a line in the privacy policy, but no banner/cookie is required for this to run.) ## Testing - `tsc --noEmit` and `next build` — clean. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
tudor added 1 commit 2026-07-21 15:03:32 +00:00
feat(analytics): load Umami heatmap recorder
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m4s
PR Checks / Backend Smoke (pull_request) Successful in 7s
PR Checks / Build Backend (no push) (pull_request) Successful in 11s
PR Checks / Build Frontend (no push) (pull_request) Successful in 47s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 10s
PR Checks / AI Code Review (Claude) (pull_request) Failing after 42s
1f80571b1f
Adds the Umami session recorder (recorder.js) that powers heatmaps,
alongside the existing analytics tracker. Loaded via next/script with
the same data-domains guard as the main tracker so it only fires on the
production hostnames — staging runs the same image under a different
host and must not feed the heatmap.

Cookieless: recorder.js uses Umami's server-side session model (no
cookie or local storage on the device), so it adds no new PECR
consent trigger.

Verified with tsc --noEmit and next build.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
tudor merged commit 7e3096c881 into main 2026-07-21 15:06:04 +00:00

🤖 AI Code Review (Claude Code)

This PR adds Umami's session-recorder/heatmap script alongside the existing analytics script.js, gated with the same data-domains hostname restriction so it only fires on production. The change is mechanically simple but introduces a session-replay tracker with no accompanying consent mechanism anywhere in the codebase.

🔴 Severe (blocks merge)

  • nextjs-app/app/layout.tsx: The new recorder.js session-replay script loads unconditionally for every visitor on every page (via the root layout), with no cookie/consent banner or opt-in gate found anywhere in the repo. It will capture user interactions including the school-search/postcode input (SchoolSearchModal.tsx) and other form fields. Session recording is non-essential tracking under UK PECR/GDPR and capturing postcodes (personal data) without consent is a compliance and data-leak risk to a third-party analytics vendor.
## 🤖 AI Code Review (Claude Code) This PR adds Umami's session-recorder/heatmap script alongside the existing analytics script.js, gated with the same data-domains hostname restriction so it only fires on production. The change is mechanically simple but introduces a session-replay tracker with no accompanying consent mechanism anywhere in the codebase. ### 🔴 Severe (blocks merge) - **nextjs-app/app/layout.tsx**: The new recorder.js session-replay script loads unconditionally for every visitor on every page (via the root layout), with no cookie/consent banner or opt-in gate found anywhere in the repo. It will capture user interactions including the school-search/postcode input (SchoolSearchModal.tsx) and other form fields. Session recording is non-essential tracking under UK PECR/GDPR and capturing postcodes (personal data) without consent is a compliance and data-leak risk to a third-party analytics vendor.
Sign in to join this conversation.
No Reviewers
No labels
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: tudor/school_compare#77