Overview
This developer guide will assist you in configuring your web platform for Session Replay using the Mixpanel JavaScript SDK. Learn more about viewing captured Replays in your project here. By default, Session Replay is disabled and will not be loaded into your application until explicitly enabled. In most cases, implementation is extremely simple, requiring only a single line of code to be changed.Prerequisite
You are a Mixpanel customer and have the latest version of the Mixpanel Javascript SDK installed (minimum supported version isv2.50.0). If not, please follow this doc to install the SDK.
Data Residency
If your Mixpanel project lives in the EU or India data center, or you route all Mixpanel traffic through a self-hosted proxy, setapi_host when you initialize the JavaScript SDK. Session Replay reuses the same api_host — there is no separate replay endpoint to configure.
| Region | api_host value |
|---|---|
| US (default) | https://api.mixpanel.com |
| EU | https://api-eu.mixpanel.com |
| India | https://api-in.mixpanel.com |
Javascript
api_host. If you also need the SDK to load its async module bundles (including the recorder) through your proxy instead of cdn.mxpnl.com, see Self-Hosted Proxy for the full setup.
Learn more about EU Data Residency and India Data Residency.
Capturing Replays
You can capturing replay data using a sampling method (recommended), or customize when and where replays are captured manually using Session Replay methods provided by the SDK.Sampling
We recommend using the sampling method unless you need to customize when you capture replay data. When the SDK initializes, it makes a sampling decision based on your configured sampling rate. A percentage of initializations will trigger session recording accordingly. To enable Session Replay and set your sampling rate, set therecording_sessions_percent when initializing the SDK. This is the only change needed in your existing JavaScript SDK implementation to enable Session Replay.
To start, we recommend using an 100% sampling rate to ensure replay capture is behaving as expected, then adjust according to your specific analytics needs.
Javascript
Manual Capture
To programatically start and stop replay capture, use thestart_session_recording() and stop_session_recording() methods. This is optional, and can be used primarily to programmatically start and stop recording, or exclude something specific from recording.
Start Capturing Replay Data
Callstart_session_recording() to force recording to begin, regardless of the record_sessions_percent init option.
This will have no effect if replay data collection is already in progress.
Example Usage
Javascript
Pause Capturing Replay Data
Callpause_session_recording() to pause any active replay data collection but do not clear the active recording.
Example Usage
Javascript
Resume Capturing Replay Data
Callresume_session_recording() to resume replay data collection.
This will have no effect if there is no non-active recording that was previously paused.
Example Usage
Javascript
Stop Capturing Replay Data
Callstop_session_recording() to stop any active replay data collection.
This will have no effect if there is no replay data collection in progress.
Example Usage
Javascript
Example Scenarios
| Scenario | Guidance |
|---|---|
| We have a sensitive screen we don’t want to capture | When user is about to access the sensitive screen, call mixpanel.stop_session_recording(). To resume recording once they leave this screen, you can resume recording with mixpanel.start_session_recording() |
| We only want to record certain types of users (e.g. Free plan users only) | Using your application code, determine if current user meets the criteria of users you wish to capture. If they do, then call mixpanel.start_session_recording() to force recording on |
| We only want to record users utilizing certain features | When user is about to access the feature you wish to capture replays for, call mixpanel.start_session_recording() to force recording on |
Cross-Origin iFrame Recording (Requires minimum SDK version: 2.76)
Session Replay captures content from cross-origin iframes embedded within your page, delivering a unified replay experience across parent pages and embedded third-party content. To enable this feature, you must explicitly allowlist domains using record_allowed_iframe_origins for security purposes. Example Usage On your parent sitewww.yoursite.com, specify the origins from which recording data is accepted:
https://embedded-widget.example.com, add the parent page’s origin to record_allowed_iframe_origins:
Additional Configuration Options
You can customize the behavior of replay captures by using the init options outlined below. Example UsageJavascript
Init Options
| Option | Description | Default |
|---|---|---|
record_block_class | CSS class name or regular expression for elements which will be replaced with an empty element of the same dimensions, blocking all contents. | new RegExp('^(mp-block|fs-exclude|amp-block|rr-block|ph-no-capture)$') (common industry block classes) |
record_block_selector | CSS selector for elements which will be replaced with an empty element of the same dimensions, blocking all contents. | "img, video" |
record_idle_timeout_ms | Duration of inactivity in milliseconds before ending a contiguous replay. A new replay collection will start when active again. | 1800000(30 minutes) |
record_mask_all_text | When true, all text is masked by default. Use record_unmask_text_selector to selectively reveal elements. | true |
record_mask_text_selector | CSS selector or array of selectors for elements to mask. Only applies when record_mask_all_text is false. | undefined |
record_unmask_text_selector | CSS selector or array of selectors for elements to unmask. Only applies when record_mask_all_text is true. | undefined |
record_mask_text_class | CSS class name or regular expression for elements that will have their text contents masked. Included for backward compatibility. | new RegExp('^(mp-mask|fs-mask|amp-mask|rr-mask|ph-mask)$') (common industry mask classes) |
record_mask_all_inputs | When true, all inputs are masked by default. Use record_unmask_input_selector to selectively reveal inputs. Note: certain input types are always masked regardless of this setting. | true |
record_mask_input_selector | CSS selector or array of selectors for inputs to mask. Only applies when record_mask_all_inputs is false. | undefined |
record_unmask_input_selector | CSS selector or array of selectors for inputs to unmask. Only applies when record_mask_all_inputs is true. | undefined |
record_max_ms | Maximum length of a single replay in milliseconds. Up to 24 hours is supported. Once a replay has reached the maximum length, a new one will begin. | 86400000(24 hours) |
record_min_ms | Minimum length of a single replay in milliseconds. Up to 8 seconds is supported. If a replay does not meet the minimum length, it will be discarded. | 0(0 seconds) |
record_sessions_percent | Percentage of SDK initializations that will qualify for replay data capture. A value of “1” = 1%. | 0 |
record_canvas | When true, Mixpanel will record snapshots of <canvas> elements on your site at up to 15 frames per second | false |
record_heatmap_data | When true, Mixpanel will capture click events during replays to populate Heatmaps. You can learn more here. | false |
record_console | When true, Mixpanel will record console logs, warnings, and errors as part of the replay. | true |
record_network | When true, Mixpanel will record network requests as part of the replay. See Network Recording for details. | false |
record_network_options | Configuration for network recording behavior, including which headers/bodies to capture. See Network Recording Options. | {} |
remote_settings_mode | Setting for handling remote configuration during SDK initialization. Can be disabled, fallback, strict. | disabled |
Network Recording
Network recording is available in SDK version
v2.76.0 and above.record_network to true in your init options.
Example Usage
Network Recording Options
For more control, userecord_network_options to customize what gets recorded.
Options Reference
| Option | Type | Description | Default |
|---|---|---|---|
initiatorTypes | InitiatorType[] | Resource types to capture. Supported types include: fetch, xmlhttprequest, img, script, link, css, audio, video, beacon, and others. | All types |
ignoreRequestUrls | string[] | List of URL patterns (matched as regex) to exclude from recording. | [] |
ignoreRequestFn | (data: NetworkRequest) => boolean | Custom function to filter out requests. Return true to ignore a request. The function receives the network request data including URL, method, status, and any recorded headers. | () => false |
recordHeaders | { request: string[], response: string[] } | Allowlist of header names to record for requests and responses. Header names are case-insensitive. Only headers in this list will be captured. | { request: [], response: [] } |
recordBodyUrls | { request: string[], response: string[] } | URL patterns (matched as regex) for which to record request and response bodies. Bodies are only recorded for fetch and xmlhttprequest initiator types. | { request: [], response: [] } |
recordInitialRequests | boolean | When true, captures resource timing entries for requests that completed before recording started (e.g., initial page load resources). | false |
How It Works
Network recording uses two complementary mechanisms:- Performance Observer: Captures timing data for all resource types (images, scripts, stylesheets, etc.) using the browser’s PerformanceObserver API. This provides URL, status code, start/end times, and initiator type.
- Fetch & XHR monkey-patching: For
fetchandxmlhttprequestrequests, the SDK wraps the native APIs to capture headers and bodies (when configured). Importantly, the SDK does not modify the original request arguments or block requests while reading response bodies — response bodies are cloned asynchronously to avoid impacting your application’s performance.
Remote Configuration
Available only for customers with a paid session replay add-on. Requires version 2.74.0
remote_settings_mode you can quickly set SDK options for your project in Mixpanel under Settings > Organization Settings > Session Replay.
Three modes are available:
disabled: Do not use remote configuration and proceed to use the hardcoded initial options provided inmixpanel.initfallback: Attempt to retrieve remote configuration and proceed with those settings. If there is failure or timeout (500 ms), will use initial provided options.strict: Will prevent session replay from auto-starting unless a remote configuration was successfully retrieved.
record_sessions_percent
remote_settings_mode options.
Example Usage
Cross-Origin Iframe Recording
Cross-origin iframe recording requires SDK version 2.77.0 or later.
Configuration
Both the parent page and the child iframe page must be configured to allow cross-origin recording.Parent Page Setup
On your parent page, add the origins of any iframes you want to record to therecord_allowed_iframe_origins array:
Child Iframe Page Setup
On the child iframe page, add the parent page’s origin torecord_allowed_iframe_origins:
Origin Format Requirements
Origins must be specified in the formatprotocol://domain[:port]. The SDK performs exact matching, so ensure your origins are formatted correctly.
| Format | Example | Valid |
|---|---|---|
| HTTPS domain | https://example.com | ✓ |
| HTTP with port | http://localhost:3000 | ✓ |
| No protocol | example.com | ✗ |
| With path | https://example.com/page | ✗ |
| Wildcard | https://*.example.com | ✗ |
Replay ID
When a replay capture begins, a Replay ID is generated by the SDK and is attached as an event property ($mp_replay_id) to events tracked by the SDK during the capture session. Events containing the same $mp_replay_id will appear in the same Replay.
If you are sending any events not coming from the SDK, add the $mp_replay_id event property to attribute the event to a specific Replay.
You can use the get_session_recording_properties() method to return the Replay ID for the current replay capture. The method will return an empty object if there is no active replay capture in progress.
Example Usage
Javascript
Server-side Stitching
Server-Side Stitching allows you to easily watch Replays for events that were not fired from the SDK. It works by inferring the Replay that an event belong using the Distinct ID and time property attached to the event. This is especially useful if you have events coming in from multiple sources (E.g. your server or warehouse import) and it does not make sense to pass around the value ofmixpanel.get_session_recording_properties().
For example, let’s say a user with Distinct ID “ABC” has a Replay recorded from 1-2pm. Two hours later, an event was sent from your warehouse with a timestamp of 1:35pm with Distinct ID “ABC”. Server-side Stitching will infer that the event should belong in the same Replay.
To ensure Server-Side Stitching works, call identify() from the client-side using our SDK with the user’s $user_id. This guarantees that events generated from both the client-side and server-side share the same Distinct ID. Learn more about identifying users.
Replay URL
Replay URLs are accessible only by authenticated users with the necessary permissions for the Mixpanel project.
get_session_replay_url() method. The method will return null if there is no Replay in progress.
This is useful for debugging or for adding metadata to other platforms. (E.g. adding replay URL to support tickets for troubleshooting)
Example Usage
Javascript
Heatmaps, Rage Clicks, and Dead Clicks (Web Only)
Therecord_heatmap_data option (Web only; not available on mobile) enables four types of interaction tracking during replay sessions:
- Click events - Captures user clicks to populate click heatmaps
- Rage clicks - Captures multiple rapid clicks on the same element (
$mp_rage_click) - Dead clicks - Captures clicks on unresponsive elements (
$mp_dead_click) - Page Leave - Captures when a page is “left” either by navigation or leaving the tab (
$mp_page_leave)
record_heatmap_data to work. Heatmaps only collect data during sessions with recorded replays. If a page has limited replay coverage, the resulting Heatmap may provide limited or less meaningful insights.
Example Usage
Javascript
Events generated by
record_heatmap_data (clicks, rage clicks, dead clicks) are exempt from your plan data allowance.Alternative: Using Autocapture for Heatmaps
If you use Autocapture to track clicks, you can leverage these clicks to populate Heatmaps without enablingrecord_heatmap_data. Autocapture also supports rage and dead click detection.
Example Usage
Javascript
Debugging
$mp_session_record is exempt from your plan data allowance.$mp_session_record) also appears in your project; you can use this to verify that Session Replay is implemented correctly.
If you are using the recommended sampling method to capture your Replays but having trouble finding the Replays in your project, try calling start_session_recording() manually and see if the $mp_session_record event appears. If it does appear but you are still struggling to locate your Replays, you may want to increase your sampling rate.
If you are still struggling to implement, submit a request to our Support team for more assistance.
Session Replay with a CDP
You can use Session Replay with customer data platforms (CDPs), such as Segment and mParticle. In order to use Session Replay, your app must have the Mixpanel Javascript SDK installed with Session Replay enabled. Once you have included the Mixpanel SDK in your app add the following code snippets in order to connect your CDP’s data stream with Mixpanel’s Session Replay.Segment: Analytics.js
By adding middleware to Segment’s SDK we can ensure that all event calls include the session replay properties. We can also ensure that any identify calls are also passed to Mixpanel.Javascript
mParticle: Web SDK
mParticle offers a direct integration for Session Replay with Mixpanel. You can configure Session Replay settings directly in your mParticle connection settings, which automatically handles session replay properties on all events.Direct Integration (Recommended)
To use the direct integration:- Ensure you have the mParticle Mixpanel Web integration enabled for your web workspace. This will load the Mixpanel JavaScript SDK and Session Replay on your site automatically via mParticle (no separate SDK install in your app code is required).
- Configure Session Replay settings in your mParticle Mixpanel connection settings, including:
- Session Recording Percentage: Percentage of SDK initializations that will qualify for replay data capture
- Record Heatmap Data: Enable heatmap, rage click, and dead click collection
- Additional privacy and configuration options as needed
$mp_replay_id) on all events forwarded through mParticle, without requiring any additional code changes.
Rudderstack: Cloud Mode
Rudderstack’s Javascript SDK has a.getAnonymousId() method which can be used to retrieve the device_id. In the following example, we use this method to bind Rudderstack’s anonymousId to Mixpanel’s device_id, as well as patching track and page event methods to include session replay properties on every Rudderstack event.
Race Condition Note (RudderStack + Heatmaps): If you are using
record_heatmap_data, set it to false at init and enable it via set_config() only after the RudderStack anonymousId has been registered. This prevents heatmap click events from firing with Mixpanel’s default $device_id before your custom identity binding completes, which can create orphaned anonymous profiles and inflate MTU counts.Javascript
Google Tag Manager
You can use session replay with Google Tag Manager (GTM). First, make sure you have the Mixpanel GTM Template installed in your workspace. Once that is added, you can add a new Mixpanel tag to your workspace which turns on Session Replay by following these instructions:- Add a new tag, and choose the Mixpanel tag type.
- For
Project Tokenfill in your Mixpanel project’s token - For
Tag Typechooseinitfrom the dropdown - For
InitializationchooseSet Options Manually - In the
Option key/Option valuedropdown, ensure you chooserecord_sessions_percentand the value should be a number between 1 and 100. - This is also where you can configure other Session Replay options like
record_block_classetc… - For the
Triggeringsection, you’ll want to choose something early in the GTM lifecycle; typically this isInitialization - All PagesorConsent Initialization - All Pagesto ensure that Session Replay starts recording as soon as the GTM container is initialized. - Save + Deploy this template to your website and you should be up and going with session replay
Privacy
Mixpanel offers a privacy-first approach to Session Replay, including features such as data masking. Mixpanel’s Session Replay privacy controls were designed to assist customers in protecting end user privacy. Read more here.User Data
By default, all text and inputs on a page are masked. You can selectively unmask elements usingrecord_unmask_text_selector and record_unmask_input_selector, or change the default behavior using record_mask_all_text and record_mask_all_inputs.
Note that certain sensitive input types (password, email, tel, hidden, and inputs with autocomplete attributes) are always masked regardless of your configuration.
Along with other data, the SDK respects all Do Not Track (DNT) settings as well as manual opt-out for any replay data.
Retention
User replays are stored for 30 days after the time of ingestion by default. Customers with the custom volumes of Session Replay can customize this value between 7 and 365 days as an additional paid add-on.Browser Storage
Session Replay stores temporary replay data in the browser using IndexedDB with dynamically generated key names prefixed with__mprec_ (short for “Mixpanel Recording”). These keys are used for session recording batchers and are constructed dynamically, for example:
__mprec_identifies the data as Session Replay recording data<instance_name>is the Mixpanel instance name (fromgetConfig('name'))<project_token>is your Mixpanel project token<replay_id>is a unique identifier for the recording session
FAQ
Can I prevent Session Replay from recording sensitive content?
By default, all on-screen text and input elements are masked in replays. You can selectively unmask elements usingrecord_unmask_text_selector and record_unmask_input_selector. Additionally, certain sensitive input types are always masked regardless of configuration. Consider the manual capture example scenarios and init options provided above to customize the replay capture of your implementation.
How can I estimate how many Replays I will generate?
If you already use Mixpanel, the Session Start events are a way to estimate the rough amount of replays you might expect. This is especially true if you use timeout-based query sessions. However, because our sessions are defined at query time, we cannot guarantee these metrics will be directly correlated. When you enable Session Replay, use the above proxy metric to determine a starting sampling percentage, which will determine how many replays will be sent. You can always adjust this as you go to calibrate to the right level.How does Session Replay affect my website’s performance?
Mixpanel leverages the open-source library, rrweb, to power Session Replay. Both rrweb and Mixpanel are designed with the highest standards of performance in mind. Below is a high-level overview of how the SDK will work on your website:- Initial Snapshot: When recording starts, rrweb takes a snapshot of the entire webpage’s structure (the DOM), assigning unique IDs to each element for change tracking.
- Change Detection: Asynchronously monitors any changes that occur to the DOM using MutationObserver, minimizing work so that we do not need to keep taking full snapshots.
- User Interactions: Listens for actions like clicks and mouse movements and throttles any high frequency events.
- Collection & Delivery: Mixpanel collects the recording data and sends it to our servers in batches every 10 seconds.
- Optimized Compression: Before sending, Mixpanel will compress the payload using the asynchronous CompressionStream API. This will optimize bandwidth while not blocking the UI thread.