CDPGuidesSupport

Privacy and Masking

Session Replay masks form inputs by default. Mask all page text, block elements, and use selector overrides for additional control.

Session Replay masks every form input by default. It also does not record <script> contents verbatim or capture <canvas> content. Page text is recorded as it appears unless you mask it. Use text masking, blocking, and path scoping to control what is captured.

BehaviorWhat appears in replay
MaskAsterisks replace text; element structure is intact
BlockBlank placeholder box; no content captured, position preserved
UnmaskReal text. This is an explicit opt-in for that element

Default masking

SurfaceDefault behaviorConfigurable?
<input> / <textarea> / <select> valuesAlways maskedNo
Page text (paragraphs, headings, links, buttons, labels)Recorded as it appearsYes, mask it all with mask_all_text or mask specific elements with the classes and selectors below
<script> textNot recorded verbatimNo
<canvas> contentNot capturedNo

Layer 1: Global text masking

Set mask_all_text: true to mask every piece of visible page text.

ours('init', '{cdp_token}', {
  session_replay: {
    token: 'replay_token',
    mask_all_text: true,
  },
});

Replay still records the page's structure (layout, scroll position, mouse trails, and click locations) while text remains masked. Use op-session-replay-ignore only for the specific text you want to make visible.

What the masked text looks like

Text masking preserves whitespace and punctuation and replaces letters and numbers with *.

OriginalMasked
Hello World***** *****
Order #1234!***** #****!
you@example.com***@*******.***
日本語テキスト*******

Whitespace and punctuation are preserved so the page layout stays stable in the replay.

A replay of an Ours Health appointment request page recorded with mask_all_text enabled, where the hero, card copy, help text, and location cards are replaced by asterisks while the site header, form field labels, and Request appointment button stay legible because they carry op-session-replay-ignore.

Layer 2: CSS classes

Add these classes to specific elements throughout your application. They work with or without mask_all_text.

<!-- Replace element with a placeholder box -->
<div class="op-session-replay-block">Sensitive content</div>

<!-- Bypass masking: text captured unredacted -->
<div class="op-session-replay-ignore">Non-essential content</div>

<!-- Mask text content -->
<div class="op-session-replay-mask">Sensitive text</div>
ClassBehavior
op-session-replay-blockElement is replaced with a placeholder box. No children, text, or inner HTML is captured, but the element's position and dimensions are preserved in replay
op-session-replay-ignoreElement is captured with full structure and text: masking is bypassed. Text appears unredacted even when mask_all_text: true is active. This does not unmask form control values; <input>, <textarea>, and <select> values remain masked
op-session-replay-maskElement's text is masked; structure is captured

In this replay, the form's field labels and its submit button carry op-session-replay-ignore, so they stay readable while the heading, helper text, and every typed value are masked.

A close-up of the masked appointment request form in a replay, with First name, Last name, Email, Phone, Service line, Preferred location, and Request appointment readable and the heading, helper text, and every field value shown as asterisks.

When to use which

  • Block PII/PHI containers, payment forms, password fields you can't otherwise reach, and any third-party iframe whose content you don't control
  • Unmask (op-session-replay-ignore) only non-sensitive elements you need legible in the replay, such as stable UI labels
  • Mask elements that may contain personal data but whose structure matters for analysis (for example, search results or customer names in an admin UI)

You can use mask_all_text: true with op-session-replay-ignore to carve out only the elements that should stay legible.


Layer 3: Selector overrides

When you can't add classes (third-party widgets, headless CMS output, code you don't own), pass CSS selectors directly.

ours('init', '{cdp_token}', {
  session_replay: {
    token: 'replay_token',
    block_selector: '.cc-card, [data-private]',
    ignore_selector: '.cc-noise',
    mask_text_selector: '.cc-pii',
  },
});
OptionEquivalent classNotes
block_selectorop-session-replay-blockAny standard CSS selector; comma-separated lists are supported
ignore_selectorop-session-replay-ignoreUnmasks matching elements. This does not unmask form control values; <input>, <textarea>, and <select> values remain masked
mask_text_selectorop-session-replay-maskMasks text inside matching elements

You can also enable mask_all_text: true and use ignore_selector to selectively reveal only the elements that need to stay visible.


Picking a strategy

If you...Start with
Have HIPAA / PHI exposuremask_all_text: true + block_selector for any container that holds sensitive information you must exclude entirely (forms, image-based sensitive information, third-party widgets)
Have PII in some pages but not mostmask_text_selector or block_selector on the affected pages as needed
Run a heavily third-party-script-driven pageblock_selector for every embed you do not control
Need to verify what's capturedRun a session, open it in the dashboard, and review before going live with new pages

Next steps

How is this guide?

On this page