Skip to content

Add PostHog analytics to the Vocs docs site#11

Open
probablyangg wants to merge 3 commits into
mainfrom
posthog-analytics
Open

Add PostHog analytics to the Vocs docs site#11
probablyangg wants to merge 3 commits into
mainfrom
posthog-analytics

Conversation

@probablyangg

Copy link
Copy Markdown
Member

Summary

The Mintlify-era PostHog integration (dev-docs/docs.jsonposthog.apiKey) was dropped in the migration to Vocs, so the new docs site sent no analytics. This restores reporting into the same PostHog project (same phc_… key + US host) so historical data stays continuous.

What changed

  • docs/lib/analytics.ts (new) — the standard PostHog browser snippet, injected via Vocs' documented head config option ("Additional tags to include in the <head>"). Loads async and independent of the app bundle, so it keeps reporting even if React fails to hydrate — mirroring what Mintlify did implicitly.
    • capture_pageview: 'history_change' — Vocs is a client-side-routed SPA; this fires $pageview on pushState/popstate so in-app navigations are tracked (the default captures the initial load only).
    • person_profiles: 'identified_only' — anonymous docs traffic shouldn't create a person profile per visitor.
  • vocs.config.ts — composes analyticsHead() with the existing SEO head() into one Fragment (Vocs' head takes a single value); removes the stale "wire PostHog later" TODO.
  • ADRs/DR006_PostHog_Analytics.md (new) — documents the decision: the head snippet vs posthog-js in a Layout (reliability vs hydration), SPA pageview handling, and the Mintlify-continuity constraint.

Kept analytics in its own module rather than structured-data.ts so that file stays single-purpose SEO (per DR001), and the analytics wiring is easy to find/remove.

Verification

  • npm run docs:build passes (Node ≥ 22).
  • The PostHog snippet is present in 379 / 379 built HTML pages; the existing JSON-LD SEO head is unaffected.
  • Not verifiable from a static build: live ingestion — confirm via PostHog's live events / a Network request to us.i.posthog.com on the deployed site.

🤖 Generated with Claude Code

The Mintlify-era PostHog integration (dev-docs/docs.json) was dropped in the
migration to Vocs, so the new site sent no analytics. Restore reporting into
the same PostHog project so historical data stays continuous.

- docs/lib/analytics.ts: standard PostHog browser snippet, injected via Vocs'
  documented `head` option (loads async, independent of the app bundle).
  capture_pageview: 'history_change' tracks SPA navigations;
  person_profiles: 'identified_only' keeps anonymous docs traffic profile-free.
- vocs.config.ts: compose analyticsHead() with the existing SEO head().
- ADRs/DR006: document the decision (head snippet vs posthog-js, SPA pageviews,
  Mintlify continuity).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jun 18, 2026

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
docs 1b6c52f Commit Preview URL

Branch Preview URL
Jun 18 2026, 02:48 PM

probablyangg and others added 2 commits June 18, 2026 10:25
PostHog was capturing pageviews + autocapture and setting cookies on
load. That is product analytics, not strictly-necessary telemetry, so it
needs prior opt-in consent under GDPR/ePrivacy. Gate it:

- Init with opt_out_capturing_by_default + persistence:'memory' — no
  capture, no cookies until the visitor opts in. An inline bootstrap
  re-applies a stored "granted" choice at load for returning visitors.
- ConsentBanner (mounted site-wide via the default Layout export) prompts
  for a choice when none is stored; Accept/Decline are equal-weight.
- A "Cookie preferences" footer link re-opens the banner so consent can
  be withdrawn as easily as it was given.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Record the opt-in consent decision layered onto DR006's PostHog
integration, and note in DR006 that its init config and "Layout slot
unused" framing are superseded by the consent gate.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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