feat(docs): expand PostHog instrumentation on the docs site - #505
Conversation
Adds the collection gaps found in the analytics audit: - docs_search (query + result_count) from the Pagefind dialog, debounced - code_copied (page + language) on Expressive Code copy buttons - docs_404 (path + referrer) via the .wh-404 marker - live_demo_engaged once per mount when the SSE feed connects - doc_section stamped on every event via a before_send hook (capture-time pathname, so the first hard-load pageview and soft navigations are both labeled correctly)
- CHANGELOG: describe the shipped before_send mechanism for doc_section (the register()/astro:before-preparation wording documented an earlier iteration that never landed) - Rename live_demo_engaged to live_demo_connected — it measures that the demo backend answered, not reader engagement - docs_search: re-arm the settle check (3 x 400ms) when Pagefind is still searching when the idle timer fires, instead of silently dropping the query (biased against cold first searches) - 404.md: record DocsTracking.astro as the third consumer of the .wh-404 marker
📝 WalkthroughSummary by CodeRabbit
WalkthroughThe docs site adds PostHog tracking for searches, code copies, 404 pages, documentation sections, live-demo connections, and CTAs. Tracking supports view transitions, delayed search capture, result counts, and one-time connection events. ChangesDocumentation analytics
Estimated code review effort: 3 (Moderate) | ~20 minutes Merge Risk: 🟡 Moderate · up to The change expands analytics collection but may send sensitive raw search or URL-derived values and can mislabel searches after client-side navigation; repeat visits to the same 404 page may also be missed. Merge should wait for sanitization and lifecycle fixes or explicit owner acceptance. Sequence Diagram(s)sequenceDiagram
participant Document
participant DocsTracking
participant Pagefind
participant PostHog
Document->>DocsTracking: receive search, copy, or 404 interaction
DocsTracking->>Pagefind: inspect search results while loading
DocsTracking->>PostHog: capture event with interaction metadata
Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
✨ Simplify code
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
📚 Docs preview is live → https://2ba41ec3-wavehouse-docs.wave-rf.workers.dev |
There was a problem hiding this comment.
Actionable comments posted: 3
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: b673daa6-2e13-46b0-b364-c8a4a844028e
📒 Files selected for processing (6)
CHANGELOG.mddocs/src/components/DocsTracking.astrodocs/src/components/Footer.astrodocs/src/components/LiveDemo.astrodocs/src/components/PostHog.astrodocs/src/content/docs/404.md
Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.
📜 Review details
⏰ Context from checks skipped due to timeout. (1)
- GitHub Check: Docs build
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{go,ts,tsx,js,jsx,md,mdx,yaml,yml,json}
📄 CodeRabbit inference engine (AGENTS.md)
Every code change updates its docs +
CHANGELOG.mdin the same PR
Files:
docs/src/content/docs/404.mdCHANGELOG.md
**/*.{md,mdx}
📄 CodeRabbit inference engine (AGENTS.md)
- Never hard-wrap prose. One paragraph is one line. No wrapping at 72/80 columns, no "semantic linefeeds" splitting a paragraph at sentence boundaries.
Files:
docs/src/content/docs/404.mdCHANGELOG.md
🪛 LanguageTool
CHANGELOG.md
[style] ~13-~13: Since ownership is already implied, this phrasing may be redundant.
Context: ...ter,LiveDemo}.astro`): the site tracked its own CTAs but nothing a reader did on the wa...
(PRP_OWN)
[style] ~13-~13: Since ownership is already implied, this phrasing may be redundant.
Context: ...docs area without each tracker carrying its own copy; it's stamped at capture time by a...
(PRP_OWN)
[style] ~13-~13: Since ownership is already implied, this phrasing may be redundant.
Context: ...ressive Code, and the 404 route all own their own markup — some of it created after page ...
(PRP_OWN)
🔇 Additional comments (5)
docs/src/components/PostHog.astro (1)
34-45: LGTM!docs/src/components/LiveDemo.astro (1)
169-173: LGTM!Also applies to: 431-444, 525-528
docs/src/components/DocsTracking.astro (1)
68-82: LGTM!docs/src/components/Footer.astro (1)
17-17: LGTM!Also applies to: 189-195
CHANGELOG.md (1)
11-13: LGTM!
CodeRabbit: a reader can click a result before the debounce or a retry fires; capturing then stamps the event with the destination page's doc_section. Bind the timer to its source pathname and drop the capture when it no longer matches.
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
docs/src/components/DocsTracking.astro (1)
53-60: 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick winKey 404 de-duplication by page instance, not pathname.
window.__whPh404Pathis never reset. After client-side navigation away from a 404 page and back to the samelocation.pathname,whCapture404()drops the second visit. This records once per pathname for the document lifetime, although the comment says “once per visit.”Store the current
.wh-404element, or reset the key on each route transition, so duplicate lifecycle callbacks are suppressed without dropping later visits.Proposed fix
function whCapture404() { - if (!document.querySelector('.wh-404')) return; - if (window.__whPh404Path === location.pathname) return; - window.__whPh404Path = location.pathname; + var marker = document.querySelector('.wh-404'); + if (!marker || window.__whPh404Marker === marker) return; + window.__whPh404Marker = marker; window.posthog?.capture('docs_404', {
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 3d27a110-656b-4f87-a897-5991bc9ced46
📒 Files selected for processing (1)
docs/src/components/DocsTracking.astro
Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.
📜 Review details
🔇 Additional comments (2)
docs/src/components/DocsTracking.astro (2)
17-21: LGTM!Also applies to: 34-34, 68-68
22-47: LGTM!Also applies to: 63-86, 90-91
Summary
The site tracked its own CTAs but nothing readers did on the way to one. This adds the collection gaps from the analytics audit:
docs_search(query,result_count) — Pagefind queries, debounced to the settled query; zero-result searches are the point (docs gaps). Re-arms the settle check while a search is in flight so cold first searches aren't dropped.code_copied(page,language) — Expressive Code copy buttons, delegated document-level; the hero install chip keeps its ownhero_install_copied.docs_404(path,referrer) — broken inbound links become a list instead of a hunch.live_demo_connected— once per mount when the hero's SSE feed comes up; named for what it measures (backend answered), not reader engagement.doc_sectionon every event via abefore_sendhook — capture-time pathname, so the first hard-load pageview and soft navigations are both labeled correctly (a queuedregister()would replay after the first pageview is already captured).New
DocsTracking.astrohosts the three site-wide trackers, rendered from the footer likeMermaidZoom/ScrollHints.Test plan
make build-docsgreen (astro check, build, Pagefind index, links validator)make verifygreen (docs-only change — classifier: code=false docs=true)index.html+404.html,before_sendhook emittedRelated Issues
None — follow-up from the PostHog analytics audit (2026-08-20).