Session recording captures exactly what users do in your app — every click, form input, and page navigation. This is crucial when you need to understand why users are abandoning checkout, where they're getting stuck, or what broke in production.
How Session Recording Works in PostHog
PostHog records sessions automatically once you initialize the SDK. It captures the DOM state, user interactions, and network activity without requiring extra setup.
Initialize PostHog with Session Recording Enabled
When you load the PostHog JavaScript SDK, session recording is enabled by default. PostHog will start capturing user interactions immediately. You can also explicitly configure it with the session_recording property.
import posthog from 'posthog-js'
posthog.init('your-api-key', {
api_host: 'https://us.posthog.com',
session_recording: {
recordCanvas: false,
maskAllInputs: true,
maskAllText: false,
},
})Session Replay Captures Full User Journeys
PostHog records every interaction — clicks, form fills, scrolls, navigation, and network requests. The replay is a video-like playback of exactly what happened in the user's browser. This data persists for 30 days by default.
// Access the session ID to link events to a specific recording
const sessionId = posthog.get_session_id()
console.log(`Current session: ${sessionId}`)
// Sessions are automatically linked to events — no manual work needed
posthog.capture('checkout_error', {
error_code: 'payment_declined',
// This event is automatically tied to the session recording
})recordCanvas: false to exclude canvas rendering and reduce file size.Configuring What Gets Recorded
PostHog lets you control what data is captured for privacy and performance reasons. You can mask sensitive inputs, exclude specific elements, and redact text.
Mask Sensitive Form Inputs
Set maskAllInputs: true to automatically mask all form fields so credit card numbers, emails, and passwords aren't recorded. You can also selectively unmask specific fields with the data-ph-unmask attribute.
// In HTML, unmask fields you want visible:
// <input type="email" class="user-email" data-ph-unmask />
// Or configure in PostHog init:
posthog.init('your-api-key', {
api_host: 'https://us.posthog.com',
session_recording: {
maskAllInputs: true,
// maskAllText: true masks all visible text too
},
})Exclude Elements from Recording
Use the mask-session-recording class or data-ph-mask attribute to exclude specific DOM elements from being captured. This is useful for hiding third-party widgets, sensitive dashboards, or PII.
// In HTML, mark elements to exclude:
// <div class="mask-session-recording">This won't be recorded</div>
// <div data-ph-mask>Neither will this</div>
// PostHog automatically skips these during playback
// Use this for:
// - Payment processor iframes
// - Customer data dashboards
// - Internal admin panelsAccessing Recordings in PostHog
Once data is recorded, you can find and watch session replays directly in the PostHog UI or programmatically via the API.
View Recordings in the PostHog Dashboard
Go to Session Replays in the left sidebar. You'll see a list of all recordings ordered by recency. Click any session to play it back. You can filter by user, event, or date range. The replay shows a timeline synced to events that occurred during that session.
// You can programmatically trigger navigation to a session:
window.location.href = `https://app.posthog.com/sessions/${sessionId}`
// Or access the PostHog API to fetch session metadata:
fetch('https://us.posthog.com/api/projects/{project-id}/session_recordings', {
headers: {
Authorization: `Bearer ${apiToken}`,
},
})
.then(r => r.json())
.then(data => console.log(data))Filter Recordings by User Behavior
In Session Replays, use filters to find specific recordings. Filter by page visited, event triggered, user cohort, or session duration. This lets you zero in on users who hit errors, abandoned checkout, or got stuck on a specific page.
// When capturing events, add properties that make filtering easier:
posthog.capture('checkout_abandoned', {
cart_value: 249.99,
step: 'payment',
reason: 'payment_failed',
})
// Now in PostHog UI, filter: Event = 'checkout_abandoned' AND step = 'payment'
// This will show you only the sessions where users hit that specific errorCommon Pitfalls
- Forgetting that maskAllInputs protects form fields but not text content — if you have PII in visible text, it still gets recorded. Use
maskAllText: trueor themask-session-recordingclass. - Enabling recordCanvas: true for sites with auto-playing videos or animated charts. This bloats recordings and kills performance. Keep it false unless you specifically need canvas playback.
- Not cleaning up old recordings — they count against your storage quota. PostHog deletes them after 30 days, but if you're over limit, new recordings won't capture.
- Assuming network requests show response bodies. They don't for security. If debugging an API error, cross-reference with server logs.
Wrapping Up
Session recording in PostHog gives you a video-like replay of exactly what users experienced. Enable it, configure privacy settings so you're not capturing PII, then use the replays to debug errors and understand drop-off points. If you want to track this automatically across tools, Product Analyst can help.