Instrument Session Replay
Note
Session Replay is currently in private preview. Grafana Labs offers support on a best-effort basis, and breaking changes might occur prior to the feature being made generally available.
On this page, you’ll learn how to install and instrument Session Replay in Faro.
Before you begin
To use Session Replay, you need:
- A Grafana Cloud account.
- An application instrumented with the Faro Web SDK v2.
npminstalled on your machine.
Install the Faro Instrumentation Replay package
To install Session Replay:
- Open your terminal.
- Navigate to your application folder.
- Run:
npm install @grafana/faro-instrumentation-replayInstrument your application
To enable Session Replay in your application:
Import the
faro-instrumentation-replaypackage:import { ReplayInstrumentation } from '@grafana/faro-instrumentation-replay'; // Make sure to import Faro as well import { getWebInstrumentations, initializeFaro } from '@grafana/faro-web-sdk';Pass the
ReplayInstrumentationobject when initializing Faro:initializeFaro({ // Mandatory, the URL of the Grafana Cloud collector with embedded application key. // Copy from the configuration page of your application in Grafana. url: 'http://faro-collector-us-central-0.grafana.net/collect/{app-key}', // Mandatory, the identification label(s) of your application app: { name: 'my-app', version: '1.0.0', // Optional, but recommended }, instrumentations: [ ...getWebInstrumentations(), new ReplayInstrumentation() ], });
Refer to configuration options for more details on how to customize your session recordings.
Understand data masking and sub-sampling
Before you record sessions in production, it’s important to understand how Session Replay protects sensitive data and how it controls the volume of recordings you collect.
Data masking
Session Replay includes masking and privacy configuration options so that you can control exactly what is and isn’t recorded, and make sure there’s no sensitive or personal data being exposed in session recordings.
All input values and text content are masked by default, client-side, before data leaves the browser. You can make masking more selective by using the maskAllInputs and maskInputOptions properties, or by using CSS selectors combined with the maskTextSelector and blockSelector properties. You can also use the beforeSend hook to filter or transform events before sending them.
After making changes to your input masking properties, make sure to test your configuration locally or in development environments before enabling it in production.
Caution
Personally identifiable information (PII) in page URLs is not masked.
For the full list of privacy properties, refer to Privacy and masking options. For broader guidance on what data is recorded and how to meet privacy requirements, refer to Data privacy in Session Replay.
Sub-sampling
Frontend Observability with Session Replay has two independent layers of sampling:
- Frontend session sampling: Controls which sessions Faro collects telemetry for (logs, errors, traces).
- Session Replay sampling: Controls what fraction of those sessions also get a recording, configured via
samplingRateonReplayInstrumentation.
For example, a Faro samplingRate of 1.0 combined with a replay samplingRate of 0.1 means telemetry is collected for all sessions, but only 10% of those sessions have a recording:
initializeFaro({
url: 'https://your-faro-endpoint.com',
sessionTracking: {
samplingRate: 1.0, // collect telemetry (logs, errors, web-vitals) for all sessions
},
instrumentations: [
...getWebInstrumentations(),
new ReplayInstrumentation({
samplingRate: 0.1, // record replay for only 10% of sessions
}),
],
});
// Effective replay coverage: 1.0 × 0.1 = 10% of globally sampled sessionsTo ensure you have recordings for the sessions you care about most, review any existing Frontend Session sampler logic to control which sessions are kept or dropped upstream. Refer to the Faro Sampling docs.
Configuration options
You can customize how Session Replay records sessions by passing options to ReplayInstrumentation. The following tables list the available recording, privacy and masking, and hook options, along with their types and default values.
Recording options
Privacy and masking options
maskInputOptions
Hooks
Examples
The following examples show common ways to configure ReplayInstrumentation. Use them as a starting point and adjust the masking and privacy options to match your application’s requirements.
Mask passwords only configuration
new ReplayInstrumentation({
// Disable global input masking and use selective masking rules instead
maskAllInputs: false,
// Mask all password inputs
maskInputOptions: { password: true },
// Override default CSS selector to stop masking text content
maskTextSelector: undefined,
})Advanced privacy configuration
new ReplayInstrumentation({
// Disable global input masking and use selective masking rules instead
maskAllInputs: false,
// Mask all text and email inputs, but allow number inputs
maskInputOptions: {
password: true,
text: true,
email: true,
tel: true,
textarea: true,
},
// Mask elements with specific CSS classes
maskTextSelector: '.sensitive-data, .pii',
// Block elements completely from recording
blockSelector: '.payment-form, .credit-card-info',
// Ignore certain elements (won't be recorded at all)
ignoreSelector: '.analytics-widget',
// Filter or transform events before sending
beforeSend: (event) => {
// Example: Skip events that might contain sensitive data
// type 3 = IncrementalSnapshot, source 9 = CanvasMutation
if (event.type === 3 && event.data?.source === 9) {
return null; // Skip this event
}
return event; // Send the event as-is
},
});Best practices
Override maskTextSelector default value to display elements
The maskTextSelector option accepts a CSS selector string and masks any matching elements in your Session Replay recordings. The default value is '*', which means it’ll match and mask all elements on a page, regardless of other options.
To make sure your masking configuration options work correctly when using maskAllInputs and maskInputOptions, override the maskTextSelector default value:
new ReplayInstrumentation({
// Disable global input masking and use selective masking rules instead
maskAllInputs: false,
// Mask all password and email inputs
maskInputOptions: {
password: true,
email: true,
},
// Override default CSS selector to display other inputs
maskTextSelector: null,
})Use maskTextSelector to mask all elements with a CSS class
The maskTextSelector option accepts a CSS selector string and masks any matching elements in your Session Replay recordings.
To selectively mask specific elements, add a class such as masked to any element you want redacted, then pass that class as the selector. This works regardless of which CSS framework you use:
new ReplayInstrumentation({
// Disable global input masking and use selective masking rules instead
maskAllInputs: false,
// Mask all text and email inputs, but allow number inputs
maskInputOptions: {
password: true,
text: true,
email: true,
tel: true,
textarea: true,
},
// Mask elements with specific CSS classes
maskTextSelector: '.masked',
});

