Session recording shows you exactly what your users are doing on your site — where they click, how they scroll, what forms they abandon. Without it, you're guessing about friction. PostHog's session recording is straightforward to enable, but you need to handle privacy correctly from the start.
Enable Session Recording and Initialize the SDK
Start in your project settings, then configure the SDK to capture sessions.
Turn on session recording in project settings
In PostHog, go to Project Settings > Session Recording and toggle the switch on. This enables PostHog to store session data for your project.
// No SDK code needed yet — toggle is in the UI
// Once enabled in settings, initialize the SDK in your appInitialize the PostHog SDK with recording enabled
In your app's entry point (e.g., pages/_app.js in Next.js or index.js in React), call posthog.init() with capture_session_recordings set to true.
import posthog from 'posthog-js';
posthog.init(process.env.NEXT_PUBLIC_POSTHOG_KEY, {
api_host: 'https://us.posthog.com',
capture_session_recordings: true
});Verify recordings are flowing
Use your site normally, then check Session Recordings in PostHog. New sessions should appear within seconds. If nothing shows, confirm Project Settings > Session Recordings is still toggled on.
// Check if session recording is enabled
if (posthog.get_config('capture_session_recordings')) {
console.log('Session recording is active');
}Configure Privacy and Masking
Session recordings capture everything by default — including passwords, credit cards, and personal data. Mask sensitive fields before they reach PostHog.
Enable text and input masking
Set mask_all_text and mask_all_inputs to true in your SDK config. This replaces all visible text and input values with asterisks before sending data to PostHog.
posthog.init(process.env.NEXT_PUBLIC_POSTHOG_KEY, {
api_host: 'https://us.posthog.com',
capture_session_recordings: true,
mask_all_text: true,
mask_all_inputs: true
});Unmask non-sensitive elements
If you've enabled global masking but want to see text in specific elements (product names, section headers, error messages), add the CSS class ph-no-capture to those elements.
// In your JSX
<div className="ph-no-capture">
<h2>Premium Features</h2>
<p>Unlock advanced analytics</p>
</div>
// Or dynamically
element.classList.add('ph-no-capture');Block sensitive sections entirely
For payment forms, login pages, or credential fields, add ph-no-capture to the parent container. PostHog won't record anything inside it — not even the page structure.
<form className="ph-no-capture">
<input type="password" placeholder="Enter password" />
<input type="email" placeholder="Email" />
<button>Sign In</button>
</form>mask_all_text: true) makes replays hard to read — you'll see asterisks instead of user input. For non-sensitive apps (internal dashboards, B2B tools), consider disabling masking to get more context.Access and Filter Session Replays
Once recordings flow in, search and filter sessions to find relevant replays.
Open the Session Recordings dashboard
In PostHog, click Session Recordings in the left sidebar. You'll see a list of all sessions with duration, device type, and last activity.
// Fetch sessions via the PostHog API (requires API key)
const POSTHOG_API_KEY = process.env.POSTHOG_API_KEY;
const project_id = process.env.POSTHOG_PROJECT_ID;
fetch(`https://us.posthog.com/api/projects/${project_id}/session_recordings/`, {
method: 'GET',
headers: {
'Authorization': `Bearer ${POSTHOG_API_KEY}`
}
})
.then(res => res.json())
.then(data => console.log(data.results));Filter sessions by user or behavior
Click Filters to narrow down sessions. Filter by User Properties (e.g., plan = 'pro'), Events (sessions with an error event), or Duration (sessions longer than 5 minutes).
// Identify users with properties for filtering
posthog.identify('user_456', {
email: '[email protected]',
plan: 'pro',
team_size: 12
});Watch a replay and jump to key events
Click a session row to open the replay. The timeline on the left shows clicks, form submissions, and page views. Click any event to jump to that moment in the recording.
// No SDK code needed — replay viewer is UI-based
// Click session row → watch replay → click events in timeline to jumpCommon Pitfalls
- Forgetting
capture_session_recordings: truein the SDK config — the feature won't work even if it's enabled in project settings. - Using
mask_all_text: trueand then complaining replays look blank. Test unmasking withph-no-captureto find the right balance. - Leaving payment forms, login fields, and password inputs unmasked, exposing sensitive data.
- Recording at 100% sample rate on high-traffic sites and exceeding your data limit. Lower the sample rate to 10–25% in project settings.
Wrapping Up
Session recording surfaces the moments users spend time, where they get stuck, and what confuses them. With privacy configured and filters set up, you'll spot friction that metrics alone miss. If you want to correlate session behavior with conversion metrics and track this across multiple tools, Product Analyst can help.