Protecting Form Data in Microsoft Clarity Session Replays
Clarity’s default input masking doesn’t cover custom editors or third-party widgets. Learn how to explicitly mask fields, ignore sensitive UI, and verify replays before rollout.
20 Sept 2025, 09:33 UTC

The problem: replays can capture what users type
You install Microsoft Clarity to watch session replays and spot where users get stuck. Clarity does not record video; it rebuilds the page’s DOM so you can replay interactions. That means any text present in the page’s HTML—email addresses, support ticket contents, credit-card fragments—can appear in a replay unless it is masked.
Clarity masks standard text, password, and numeric inputs by default. It does not automatically obscure custom rich-text editors, third-party chat widgets, or content injected by JavaScript after the page loads. If your team assumes the default is enough, sensitive data can reach Clarity’s servers.
The practical takeaway: treat automatic masking as a baseline, not a guarantee. Explicitly mask custom fields, ignore non-sensitive UI, and gate recording on user consent before you deploy to production.
What default masking covers and where it fails
- Covered by default:
<input type="text">,<input type="password">,<input type="number">, and similar native form fields. - Not reliably covered:
contenteditabledivs, custom dropdowns, WYSIWYG editors, third-party widgets, and fields populated dynamically after initial load.
Because session replay reconstructs DOM state, a masking rule must match the element as it exists when Clarity captures it. A field added by a React or Vue component after mount needs a rule applied after it appears.
Worked example: mask a custom editor and ignore a chat widget
Suppose your support page has a custom rich-text editor and a third-party chat widget. You want the editor’s content masked and the widget excluded entirely.
<!-- Custom editor: mask its text in replays -->
<div contenteditable="true" class="rt-editor" data-clarity-mask></div>
<!-- Third-party widget: ignore completely -->
<div id="support-chat" data-clarity-ignore></div>
<!-- Native password field: masked by default; explicit attribute is optional -->
<input type="password" name="password" data-clarity-mask>
For elements added dynamically, use the Clarity JavaScript API after the snippet loads:
// Mask a dynamically rendered editor
clarity("mask", ".rt-editor");
// Ignore a dynamically injected widget
clarity("ignore", "#support-chat");
Where to run: in your frontend JavaScript bundle or an inline script on the page, after the Clarity snippet has loaded. Required permissions: write access to the site’s frontend code and the ability to deploy to a test environment. Placeholders like .rt-editor and #support-chat must match your actual markup.
Risks: over-masking hides UI defects you may want to observe; under-masking leaks personal data. Apply rules selectively and review them when you change the frontend.
Control recording by consent and URL
Clarity does not replace a consent management platform. Use your CMP to decide when recording starts:
// Example only; integrate with your actual consent manager
if (consentGranted) {
clarity("enable");
} else {
clarity("disable");
}
You can also exclude specific URLs in Clarity project settings, or add data-clarity-ignore to pages or elements you never want recorded. These controls reduce data collection, which also reduces the chance of accidental capture.
Verify before you roll out
- Install the Clarity snippet on a test page, not production.
- Enter a unique test string such as
VERIFY-MASK-TEST-999into every masked field. - Start a session, interact with the fields, then open the replay in Clarity.
- Confirm masked fields appear obscured or blank, not as plaintext.
- Open browser DevTools, inspect the masked elements, and confirm
data-clarity-maskordata-clarity-ignoreis present. - Check the Network tab for requests to Clarity endpoints; masked field values should not appear in plaintext in the payload. Note that payloads may be encoded, so absence of plaintext is a signal, not a guarantee.
- Repeat with an ad blocker or strict privacy settings enabled to observe coverage gaps.
Limitations
- Clarity’s free tier has no published SLA, and feature limits can change. Do not use it as a compliance-critical audit trail without reviewing current terms.
- Ad blockers and browser privacy features can block the Clarity script, creating replay coverage gaps.
- Masking rules must be maintained as your frontend changes; a new component can bypass an old rule.
- Clarity is designed with GDPR and CCPA in mind, but it does not establish a lawful basis for recording or replace required disclosures.
Rollback
Installing the snippet changes state because it begins sending session data to Clarity. To roll back, remove the Clarity <script> block from your pages and redeploy. Data already collected remains subject to Microsoft’s retention and deletion policies; consult Clarity project settings to delete a project if required.
Closing checklist
- Mask custom editors and third-party widgets explicitly.
- Gate recording on consent through your CMP.
- Verify masked fields on a test page before production.
- Review current Clarity terms and data residency before relying on it for regulated data.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.