How to add session replay to your website
This guide walks you through enabling session replay with OpenPanel. By the end, you'll be recording real user sessions you can play back in the dashboard to understand exactly what your users did.
Session replay captures clicks, scrolls, and interactions as structured data—not video. Privacy controls are built in, and the replay module loads asynchronously so it never slows down your main analytics.
Prerequisites
- An OpenPanel account
- Your Client ID from the OpenPanel dashboard
- Either the
@openpanel/webnpm package installed, or access to add a script tag to your site
Install OpenPanel
If you're starting fresh, add the OpenPanel script tag to your page. If you already have OpenPanel installed, skip to the next step.
<script>
window.op=window.op||function(){var n=[];return new Proxy(function(){arguments.length&&n.push([].slice.call(arguments))},{get:function(t,r){return"q"===r?n:function(){n.push([r].concat([].slice.call(arguments)))}} ,has:function(t,r){return"q"===r}}) }();
window.op('init', {
clientId: 'YOUR_CLIENT_ID',
trackScreenViews: true,
});
</script>
<script src="https://openpanel.dev/op1.js" defer async></script>Or with npm:
npm install @openpanel/webSee the Web SDK docs or Script tag docs for a full install guide.
Enable session replay
Session replay is off by default. Enable it by adding sessionReplay: { enabled: true } to your init config.
Script tag
<script>
window.op=window.op||function(){var n=[];return new Proxy(function(){arguments.length&&n.push([].slice.call(arguments))},{get:function(t,r){return"q"===r?n:function(){n.push([r].concat([].slice.call(arguments)))}} ,has:function(t,r){return"q"===r}}) }();
window.op('init', {
clientId: 'YOUR_CLIENT_ID',
trackScreenViews: true,
trackOutgoingLinks: true,
sessionReplay: {
enabled: true,
},
});
</script>
<script src="https://openpanel.dev/op1.js" defer async></script>The replay script (op1-replay.js) is fetched automatically alongside the main script. Because it loads asynchronously, it doesn't affect page load time or the size of your main analytics bundle.
NPM package
import { OpenPanel } from '@openpanel/web';
const op = new OpenPanel({
clientId: 'YOUR_CLIENT_ID',
trackScreenViews: true,
trackOutgoingLinks: true,
sessionReplay: {
enabled: true,
},
});With the npm package, the replay module is a dynamic import resolved by your bundler. It is automatically code-split from your main bundle—if you don't enable replay, the module is never included.
Next.js
For Next.js, enable replay in your OpenPanelComponent:
import { OpenPanelComponent } from '@openpanel/nextjs';
export default function RootLayout({ children }) {
return (
<html lang="en">
<body>
<OpenPanelComponent
clientId="YOUR_CLIENT_ID"
trackScreenViews={true}
sessionReplay={{
enabled: true,
}}
/>
{children}
</body>
</html>
);
}Configure privacy controls
Session replay captures real user behavior, so it's important to control what gets recorded. OpenPanel gives you several layers of control.
Input masking (enabled by default)
All form input values are masked by default. The recorder sees that a user typed something, but not what they typed. You never need to add special attributes to password or credit card fields—they're masked automatically.
If you need to disable masking for a specific use case:
sessionReplay: {
enabled: true,
maskAllInputs: false,
}Block sensitive elements
Elements with data-openpanel-replay-block are replaced with a grey placeholder in the replay. The element and all its children are completely excluded from recording.
<!-- This section will appear as a placeholder in replays -->
<div data-openpanel-replay-block>
<img src="user-avatar.jpg" alt="Profile photo" />
<p>Private user content</p>
</div>You can also configure a CSS selector or class to block without adding data attributes to every element:
sessionReplay: {
enabled: true,
blockSelector: '.payment-form, .user-profile-card',
blockClass: 'no-replay',
}Mask specific text
To mask text within an element without blocking its layout from the replay, use data-openpanel-replay-mask:
<p>
Account balance:
<span data-openpanel-replay-mask>$1,234.56</span>
</p>The span's text appears as *** in the replay while the surrounding layout remains visible.
Configure a custom selector to avoid adding attributes to every element:
sessionReplay: {
enabled: true,
maskTextSelector: '.balance, .account-number, [data-pii]',
}Ignore interactions
Use ignoreSelector to prevent interactions with specific elements from being captured. The element is still visible in the replay, but clicks and input events on it are not recorded.
sessionReplay: {
enabled: true,
ignoreSelector: '.internal-debug-toolbar',
}View replays in the dashboard
Navigate to your OpenPanel dashboard and open the Sessions view. Any recorded session will show a replay button. Click it to play back the session from the beginning.
The replay timeline shows all events alongside the recording, so you can jump directly to a click, form submission, or page navigation.
Replays are also accessible from user profiles. Open any user's profile, find a session in their history, and click through to the replay.
Performance considerations
The replay recorder buffers events locally and sends them to OpenPanel in chunks every 10 seconds (configurable via flushIntervalMs). On tab close or page hide, any remaining buffered events are flushed immediately.
The default chunk size limits are:
- 200 events per chunk (
maxEventsPerChunk) - 1 MB per payload (
maxPayloadBytes)
These defaults work well for most sites. If you have pages with heavy DOM activity, you can lower maxEventsPerChunk to send smaller, more frequent chunks:
sessionReplay: {
enabled: true,
flushIntervalMs: 5000,
maxEventsPerChunk: 100,
}Next steps
- Read the session replay docs for a full option reference
- Learn about session tracking to understand what session data is available without replay
- See how funnels and session replay work together to diagnose drop-offs


