Skip to content

feat: anonymous PostHog analytics with opt-out - #1191

Merged
snekxs merged 3 commits into
mainfrom
feat/posthog-analytics
Oct 22, 2026
Merged

snekxs merged 3 commits into
mainfrom
feat/posthog-analytics

Conversation

@snekxs

@snekxs snekxs commented Oct 22, 2026 •

Copy link
Copy Markdown
Member

What

Adds PostHog (US region) to count users, see who comes back, and see device connection errors.

  • src/platform/analytics.ts: anonymous random id in localStorage, ip: false, no autocapture, no session replay, respects Do Not Track, person_profiles: identified_only. No-op when VITE_POSTHOG_KEY / VITE_POSTHOG_HOST are unset (dev, forks, previews).
  • Events: device_connected, device_connection_failed, device_not_a_mouse, device_error (vendor id, product id, product name, scrubbed error name and message), plus pending_changes_applied, diagnostics_downloaded, hardware test and game request events. Serials, receiver ids and user text are never sent.
  • Settings: "Share anonymous diagnostics" switch (on by default), strings in all 12 locales.
  • CSP pinned to us.i.posthog.com and us-assets.i.posthog.com; tests updated.
  • JS budget 2_800_000 to 3_150_000: posthog-js added about 340 kB, measured 3_125_815.

Before merging

  • Set VITE_POSTHOG_KEY and VITE_POSTHOG_HOST in Cloudflare Pages (done by the owner).
  • Turn on "Discard client IP data" in the PostHog project settings.
  • The wizard's starter dashboard uses device_connection_succeeded; it is now device_connected.
  • A strict reading of EU ePrivacy rules wants opt-in for the stored id; this ships on by default with an opt-out.

Checks

npm run build, npm test (400 pass), npm run size pass. Not yet verified: events arriving from a deployed build.

Note

Add anonymous PostHog analytics with opt-out setting and event tracking

  • Adds a new analytics module in analytics.ts that initializes PostHog from VITE_POSTHOG_* env vars, with anonymous localStorage persistence, no IP capture, no autocapture or session recording, and scrubbing of emails, paths, hex IDs, and stack-frame URLs before events are sent
  • Instruments device connection, flashing, diagnostics, hardware tests, game requests, and profile-key copies with named events; builds without PostHog config leave analytics as no-ops
  • Adds an opt-out switch in Interface Settings (with labels in all 12 locales) that persists the PostHog opt-in/out choice
  • Updates CSP in security-headers.js and _headers to allow PostHog script and connection origins, raises the JS bundle budget from 2.8MB to 3.15MB, and allowlists posthog-js in CI
  • Risk: device.connect now emits device_connected, device_not_a_mouse, or device_connection_failed instead of the generic diagnostic event; check the suppressed generic diagnostic analytics path in controller.ts

Macroscope summarized 7504f7a.

Anonymous random id in localStorage (no IP, no autocapture, no replay) to
count users and return visits, plus device connection and error events
with model-level device facts only. Adds a Share anonymous diagnostics
switch in Interface settings (all locales), pins the CSP to the US
PostHog hosts, and raises the JS budget to 3_150_000 (posthog-js added
about 340 kB; measured 3_125_815).
@github-actions github-actions Bot added type: enhancement PR title category: enhancement area: ui Interface and styling area: devices Device integration and HID support area: translations Localized interface strings area: dependencies Dependency manifests and lockfiles area: ci Automation and build configuration labels Oct 22, 2026
@coderabbitai

coderabbitai Bot commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Note

Currently processing new changes in this PR. This may take a few minutes, please wait...

⚙️ Run configuration
📥 Commits

Reviewing files that changed from the base of the PR and between b209e5b and 7504f7a.

⛔ Files ignored due to path filters: 1
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing: 25
  • .env.example
  • .github/workflows/ci.yml
  • build/check-bundle-size.ts
  • functions/_lib/security-headers.js
  • package.json
  • public/_headers
  • src/device/controller.ts
  • src/features/games/GameRequestDialog.tsx
  • src/features/hardware-test/HardwareTestPage.tsx
  • src/features/settings/InterfaceSettings.tsx
  • src/i18n/index.ts
  • src/i18n/locales/ar.ts
  • src/i18n/locales/de.ts
  • src/i18n/locales/es.ts
  • src/i18n/locales/fr.ts
  • src/i18n/locales/ja.ts
  • src/i18n/locales/ko.ts
  • src/i18n/locales/pt.ts
  • src/i18n/locales/ru.ts
  • src/i18n/locales/tr.ts
  • src/i18n/locales/vi.ts
  • src/i18n/locales/zh.ts
  • src/main.tsx
  • src/platform/analytics.ts
  • test/security-headers.test.ts
+----------------------------------------------------------------------------------------------------------------------+
| Adapting old programs to fit new machines usually means adapting new machines to behave like old ones. - Alan Perlis |
+----------------------------------------------------------------------------------------------------------------------+
  \
   \   (\__/)
       (•ㅅ•)
       /   づ
✨ Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR

Comment @coderabbitai help to get the list of available commands.

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Oct 22, 2026 •

Copy link
Copy Markdown

Deploying openmouse with  Cloudflare Pages  Cloudflare Pages

Latest commit: 7504f7a
Status: ✅  Deploy successful!
Preview URL: https://3646cb64.openmouse.pages.dev
Branch Preview URL: https://feat-posthog-analytics.openmouse.pages.dev

View logs

Comment thread src/device/controller.ts Outdated
Comment thread src/platform/analytics.ts
@macroscopeapp

macroscopeapp Bot commented Oct 22, 2026 •

Copy link
Copy Markdown

Approvability

Verdict: Needs Human Approval

Macroscope's review found this PR requires human approval — This PR introduces default-on PostHog telemetry, automatic exception reporting, persistent browser analytics state, external CSP permissions, and a user-facing opt-out control across production paths. The integration and its privacy/data-handling implications require human review even though the supplied findings appear addressed in the final code.

Notes:

  • Your repo's Minimum Blocking Severity is Off, so correctness findings do not automatically block approval.

You can add or adjust custom eligibility rules. Learn more.

@snekxs
snekxs merged commit fa30370 into main Oct 22, 2026
8 of 9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: ci Automation and build configuration area: dependencies Dependency manifests and lockfiles area: devices Device integration and HID support area: translations Localized interface strings area: ui Interface and styling type: enhancement PR title category: enhancement

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant