Gating Microsoft Clarity on User Consent and Masking PII in Recordings
Learn how to gate Microsoft Clarity behind explicit user consent and apply masking rules to protect PII in session recordings and heatmaps.
08 Dec 2025, 14:03 UTC

Desired outcome
Session recordings and heatmaps lose their value the moment they expose personal data or load before a visitor has agreed to analytics. The goal is to capture usable behavioral data from Microsoft Clarity while ensuring that sensitive text and input fields are masked, and that the Clarity tag initializes only after an explicit consent decision.
Prerequisites
- An active Microsoft Clarity project and its project ID.
- Edit access to site HTML or a tag manager container.
- A working consent mechanism that can answer whether analytics cookies or tags are permitted.
- An inventory of CSS selectors or input types that carry PII, such as email addresses, phone numbers, payment details, or internal identifiers.
Procedure
Inventory PII selectors
Walk through core user flows and list every element that could contain personal data. Record both semantic HTML attributes and custom classes or IDs. This list becomes the basis for your masking rules.
Configure masking rules in Clarity
In the Clarity project settings, locate the masking or privacy section. Dashboard labels are version sensitive, so verify the exact wording in your current project UI. Add rules for the following categories:
| Target | Rule type | Example value | Purpose |
|---|---|---|---|
| Email fields | Input type | input[type="email"] | Mask email inputs automatically |
| Custom PII nodes | CSS selector | .user-ssn, #internal-id | Mask specific text nodes by class or ID |
| Broad text inputs | Input type | input[type="text"] | Mask all text inputs (use with caution to avoid over-masking) |
Save the rules and confirm they appear as active in the project settings list.
Gate the tag behind consent
Replace the standard unconditional Clarity snippet with a consent check. The following example assumes a simple consent flag stored in localStorage. Run this in your site HTML before the closing </head> tag, or inside a tag manager custom HTML tag with the appropriate trigger.
(function() {
// Replace with your actual consent check
function hasAnalyticsConsent() {
return localStorage.getItem('analytics_consent') === 'granted';
}
if (hasAnalyticsConsent()) {
(function(c,l,a,r,i,t,y){
c[a]=c[a]||function(){(c[a].q=c[a].q||[]).push(arguments)};
t=l.createElement(r);t.async=1;t.src="https://www.clarity.ms/tag/"+i;
y=l.getElementsByTagName(r)[0];y.parentNode.insertBefore(t,y);
})(window, document, "clarity", "script", "YOUR_PROJECT_ID");
}
})();Permissions and placement: you need deploy access to the HTML template or tag manager container. Placeholder: replace YOUR_PROJECT_ID with your real Clarity project ID. Expected check: open the browser DevTools Network tab, filter for clarity.ms, and confirm no requests fire before consent is granted. Risk: a syntax error in the wrapper can block subsequent scripts, so validate in a staging environment first.
Roll out in stages
Publish the masking rules and consent gate to a small traffic subset before enabling them site-wide. Compare page view counts and session start timestamps against the previous period to ensure collection resumes correctly after consent is granted.
Expected checks
- Network gating: in an incognito window without consent, confirm no Clarity network requests are emitted. Grant consent, reload, and confirm the script loads and a session starts.
- Masking in recordings: play a sample recording and inspect the fields you identified as sensitive. They should appear masked, while non-sensitive UI remains readable.
- Heatmap coverage: open a recent heatmap and verify that clicks and scroll depth are still meaningful on non-masked areas.
- Rule persistence: revisit the Clarity project settings and confirm the mask rules are listed as active for text nodes, inputs, and custom selectors.
Recovery options
- Over-masking: if recordings hide too much, edit or disable the specific broad rule (for example, remove
input[type="text"]) while keeping targeted selectors active. - Debugging: temporarily revert to unconditional loading to diagnose tag issues, but keep masking rules enabled so PII remains protected during debugging.
- Accidental capture: if PII was recorded despite masking, use Clarity data deletion controls to remove the affected recordings.
Limitations and version sensitivity
Masking is client-side and selector-based. Dynamic content injected after page load or elements inside shadow DOM may require additional rules and can still expose data if selectors miss. Over-masking reduces analytical value, so review masked areas against core flows before full rollout. Consent gating also delays first-session data and can create funnel gaps if consent state is not persisted consistently across pages. Finally, Clarity dashboard layout and setting names change over time; validate every step against your current project UI rather than relying on static screenshots.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.