Privacy & masking
Recording is masked by default, and anything else on the page can be masked or excluded too — either with a class in your markup or with a CSS selector in the dashboard, which applies without touching your site.
What is masked by default
Every input field. Values are replaced with **** inside the visitor's browser, before anything is transmitted — the real text never leaves the page. This covers text fields, email and password fields, textareas, selects, checkboxes, and inputs inside same-origin iframes and open shadow DOM. Network capture is metadata only (method, URL, status, duration) — never request or response bodies.
Hide any element with a class
Three class names control recording per element — no configuration needed, they always work:
<!-- text is masked in replay (shown as ****) -->
<p class="rr-mask">j.doe@example.com</p>
<!-- element is not recorded at all — replay shows a same-size placeholder -->
<div class="rr-block">
Embedded support chat
</div>
<!-- value changes to this input are not recorded -->
<input class="rr-ignore" name="internal-ref" />rr-mask— the element's text (and its children's) is recorded as asterisks. Use it for displayed PII: emails in a header, names in a table, account numbers.rr-block— the element is not recorded at all; replay shows an empty placeholder with the same dimensions. Use it for regions that should never be captured: a document preview, a chat widget.rr-ignore— changes to an input are not recorded. Only relevant if you turned input masking off and want to keep specific fields private.
Hide elements from the dashboard — no deploy
If you can't (or don't want to) edit the site's markup, set a CSS selector in Project settings → Recording privacy:
- Mask text selector — every element matching the selector is masked, like
rr-mask. - Block selector — every matching element is excluded, like
rr-block.
.account-email, [data-private]The recorder fetches these settings at startup, so changes reach your visitors within about a minute — no snippet change, no redeploy. An invalid selector safely degrades to "no extra masking"; it can never break recording. If the settings can't be fetched at all, the recorder proceeds with the strictest defaults, not the relaxations.
What masking does not cover
Two honest boundaries, so you can design around them:
- URLs are recorded in full, including query strings. If a form on your site submits via GET, typed values end up in the URL — use POST for anything sensitive, as you would for any analytics tool.
- Console capture records what your own code logs. If your app logs personal data to the console, it will appear in recordings — avoid logging PII, or disable console capture with
logcohort('init', key, { captureConsole: false }).
Masking is your choice, not your visitor's risk: the dashboard can relax input masking per project, but password fields stay masked no matter what, and recordings can never be searched by typed text — the search index is built only from URLs, errors, and clicked elements.