feat/web-replay
needs attentionviewing older commit6ef2715 · fullPR #367reviewed 2026-07-31 17:34 UTC1H · 2M · 1L · 4I- Purpose
- Enable PostHog session replay on apps/web (the public marketing site + Atlas map), which previously had the app opt-in disabled while apps/platform enabled it.
- Goal
- Extend the existing two-part session replay gate to the public site so Atlas interactions and marketing journeys are recorded in PostHog.
- Sub-goals
- SG-1: Add sessionReplay prop to <PostHogProvider> in apps/web layout
- SG-2: Update JSDoc in PostHogProvider.tsx and session-replay.ts to reflect both consumers
- What
- apps/web now passes sessionReplay to PostHogProvider. Two JSDoc comments updated to remove 'only apps/platform' language.
- Why
- Session replay on the marketing site provides visibility into Atlas map usage and lead-gen funnel behavior. The existing two-part gate (code + env var) ensures no recording in previews or staging.
- Areas
- apps/web/src/app/layout.tsx+9−1packages/analytics/src/providers/PostHogProvider.tsx+1−1packages/analytics/src/providers/session-replay.ts+1−1
- Blast
- 3 files, +11/−3. Minimal — activates a pre-built prop path that is already tested and used by apps/platform.
Findings · 8
correctness2
packages/analytics/README.md contradicts this PR in two places
packages/analytics/README.md:41
Lines 41–43 state "Today only `apps/platform` does; `apps/web` stays out on purpose." A future developer reading this will treat the `sessionReplay` prop on `apps/web` as a bug and revert it. Line 34 also says the env var should be set "ONLY in the Production environment of apps/platform" — now also applies to `apps/web`. Both need updating in this PR.
Gate wiring is correct — no non-prod recording risk
The two-half gate (sessionReplay prop AND NEXT_PUBLIC_POSTHOG_SESSION_REPLAY==='true') is correctly wired. Preview and staging builds compile without the env var so SESSION_REPLAY_ENABLED_FOR_ENV is false at bundle time. The development opt_out_capturing() is an additional backstop. All 4 gate combinations are tested.
security2
No per-app sampling or URL trigger — shared project settings affect both apps equally
apps/web/src/app/layout.tsx
Both apps share PostHog project 334265, so any sample rate or minimum-duration filter set in the console to protect against Atlas/bot traffic will also apply to apps/platform recordings and vice versa. The PR description correctly flags this as a pre-merge action, but the recommended mitigation (PostHog project settings) is coarse-grained. Using the JS `urlTriggers` init option per-app would give per-app granularity without needing console changes.
maskAllInputs: true covers the primary PII risk for these forms
apps/web has acceso/demo forms with name and email fields. maskAllInputs: true masks input values during typing. Error message nodes (state.errors?.name[0]) render validation messages, not reflected user input. No ph-no-capture class is needed for the current form structure.
conventions1
Comment block is 8 lines vs the platform's 2-line convention
apps/web/src/app/layout.tsx:71
apps/platform/src/app/[locale]/layout.tsx uses a 2-line comment for the identical concern. The 8-line block here explains PostHog project internals (project 334265, sampling) that belong in the README, not inline. Trim to match: `sessionReplay: public site records (Atlas + marketing). Also requires NEXT_PUBLIC_POSTHOG_SESSION_REPLAY=true, set in production only.`
tests2
NEXT_PUBLIC_POSTHOG_SESSION_REPLAY not documented in apps/web env files
apps/web/README.md
The env var is a merge-blocking operational requirement for this feature to activate, but it appears in no permanent documentation for apps/web (only in the PR description). A commented entry in apps/web/.env.example (or the README env table) would prevent silent misconfiguration after a project reset.
Existing tests cover the gate logic — no gap from this change
The layout change is a prop pass (sessionReplay), not new logic. session-replay.test.ts already covers all 4 gate combinations, disable_session_recording negation, maskAllInputs invariant, and option name spelling. No additional test is needed.
seo1
SEO unaffected — metadata export and canonical tags untouched
The change is purely inside the RootLayout body. The metadata export, metadataBase, openGraph, twitter, and canonical tags are unchanged. No SEO impact.