Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 2 additions & 6 deletions src/components/PostHogSetup.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
'use client'

import { useEffect } from 'react'
import { POSTHOG_REPLAY_PRIVACY_CONFIG } from '../lib/posthog-privacy'

function PostHogInitializer({ site }: { site: string }) {
useEffect(() => {
Expand All @@ -18,12 +19,7 @@ function PostHogInitializer({ site }: { site: string }) {
defaults: '2025-11-30',
capture_exceptions: true,
debug: import.meta.env.MODE === 'development',
session_recording: {
maskAllInputs: false,
maskInputOptions: {
password: true,
},
},
...POSTHOG_REPLAY_PRIVACY_CONFIG,
})
posthog.register({ site })
}
Expand Down
24 changes: 24 additions & 0 deletions src/lib/posthog-privacy.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { describe, expect, it } from 'vitest'
import { POSTHOG_REPLAY_PRIVACY_CONFIG } from './posthog-privacy'

describe('PostHog replay privacy', () => {
it('keeps session replay disabled for every shared browser surface', () => {
expect(POSTHOG_REPLAY_PRIVACY_CONFIG.disable_session_recording).toBe(true)
})

it('fails closed if session replay is enabled accidentally', () => {
expect(POSTHOG_REPLAY_PRIVACY_CONFIG).toMatchObject({
capture_performance: { network_timing: false },
enable_recording_console_log: false,
session_recording: {
maskAllInputs: true,
maskTextSelector: '*',
blockSelector: '[data-ph-sensitive]',
recordHeaders: false,
recordBody: false,
captureCanvas: { recordCanvas: false },
collectFonts: false,
},
})
})
})
21 changes: 21 additions & 0 deletions src/lib/posthog-privacy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import type { PostHogConfig } from 'posthog-js'

/**
* Session replay stays disabled on every surface that shares PostHogSetup,
* including docs, developers, and docs routes proxied through tempo.xyz.
* The remaining options fail closed if replay is ever enabled accidentally.
*/
export const POSTHOG_REPLAY_PRIVACY_CONFIG = {
disable_session_recording: true,
capture_performance: { network_timing: false },
enable_recording_console_log: false,
session_recording: {
maskAllInputs: true,
maskTextSelector: '*',
blockSelector: '[data-ph-sensitive]',
recordHeaders: false,
recordBody: false,
captureCanvas: { recordCanvas: false },
collectFonts: false,
},
} satisfies Partial<PostHogConfig>
Loading