Deciding Whether to Enable Microsoft Clarity Session Replay in Production
A decision guide for enabling Microsoft Clarity session replay in production: compare replay vs. heatmaps, implement consent-gated loading with masking and SPA route tracking, and validate with a concrete checklist.
24 May 2026, 20:28 UTC

The Decision: Replay vs. Aggregated Analytics
You need to understand user behavior on a production site, but session replay captures every click, scroll, and keystroke — creating privacy obligations and data volume that aggregated heatmaps do not. The choice is not binary; you can gate replay behind consent, mask sensitive fields, and limit it to specific routes. This guide walks through the constraints, compares the supported options, and shows a concrete consent-gated implementation with validation steps.
Constraints That Shape the Decision
- Regulatory: GDPR, CCPA, and similar laws typically require explicit consent before behavioral capture. Do not assume default masking covers all sensitive inputs.
- Data residency: Confirm regional storage and retention settings in the Clarity dashboard against organizational policy before enabling replay on authenticated or checkout flows.
- Performance: High-traffic or highly dynamic pages increase bandwidth and processing overhead. Measure before broad rollout.
- Sensitive content: Avoid replay on pages with secrets, payment data, or health information unless masking and exclusions are validated.
Supported Options Compared
| Option | Privacy Exposure | Overhead | Debugging Granularity | Typical Use Case |
|---|---|---|---|---|
| Session replay (full) | High — records inputs, clicks, scrolls | Moderate–high (script + payload) | Per-session, frame-accurate | Complex interaction bugs, funnel drop-off analysis |
| Heatmaps + aggregated metrics only | Low — no per-session identifiers | Negligible | Page-level aggregates | Layout optimization, broad engagement trends |
| Consent-gated replay | Controlled — only after opt-in | Same as full, but only for consenting users | Per-session for subset | Production debugging with compliance |
| Replay with masking + page exclusions | Reduced — sensitive fields masked, pages excluded | Same as full | Per-session minus excluded data | Authenticated areas, forms, checkout |
Trade-offs
Session replay gives you the exact user journey — invaluable for reproducing a race condition in a single-page application (SPA) or seeing why users abandon a multi-step form. The cost is privacy risk: even with masking, a replay can reveal intent, timing, and non-text interactions. Heatmaps avoid this but cannot show why a specific user failed. A consent-gated approach limits exposure to users who opt in, but reduces sample size and may bias insights toward privacy-comfortable visitors. Masking and exclusions reduce risk further but require ongoing maintenance as new fields and pages are added.
Concrete Implementation: Consent-Gated Snippet with SPA Support
Load the Clarity snippet only after the user accepts analytics cookies. For SPAs, initialize early and verify route-change capture. The following pattern works in a typical React/Next.js or Vue/Nuxt codebase.
1. Consent Gate (client-side)
// utils/clarity.ts
const CLARITY_PROJECT_ID = 'YOUR_PROJECT_ID';
function loadClarity() {
if (window.clarity) return; // already loaded
const script = document.createElement('script');
script.type = 'text/javascript';
script.async = true;
script.src = `https://www.clarity.ms/tag/${CLARITY_PROJECT_ID}`;
script.onload = () => {
// Ensure SPA route changes are tracked
if (typeof window.clarity === 'function') {
window.clarity('set', 'autoTrack', true);
}
};
document.head.appendChild(script);
}
export function initClarityIfConsented() {
// Replace with your consent management platform check
const consent = localStorage.getItem('analytics_consent') === 'true';
if (consent) loadClarity();
}
// Call on app bootstrap
initClarityIfConsented();
Where to run: In the browser, during application initialization (e.g., _app.tsx in Next.js or main.ts in Vue). Permissions: None beyond script injection. Placeholder: Replace YOUR_PROJECT_ID with the ID from your Clarity project settings. Risk: If consent logic is flawed, the script loads without consent — verify with devtools (see validation).
2. Masking Sensitive Elements
Add the data-clarity-mask attribute to any input, textarea, or element containing PII. For dynamic forms, apply after render.
<input type="email" name="email" data-clarity-mask="true" />
<textarea data-clarity-mask="true"></textarea>
<div class="credit-card-display" data-clarity-mask="true">**** 1234</div>
To exclude an entire page (e.g., checkout confirmation), add data-clarity-exclude to the <body> or a wrapper element.
<body data-clarity-exclude="true">...</body>
3. SPA Route-Change Verification
Clarity's autoTrack uses the History API. For hash-based routers or custom navigation, call clarity('pageview') manually.
// router guard example (Vue Router)
router.afterEach((to) => {
if (window.clarity) {
window.clarity('pageview', to.fullPath);
}
});
Validation Checklist
- Consent gate: Open devtools Network tab, filter for
clarity.ms. Reload page without consent — no Clarity requests should fire. Accept consent, reload, confirmtag/<PROJECT_ID>and subsequentcollectcalls appear. - Script timing: In Performance tab, measure script load time on a representative page. Target < 200 ms added to TTI on 3G.
- Masking verification: Record a test session interacting with masked fields. In the Clarity dashboard, open the replay and confirm masked elements show asterisks or blurred content, never plaintext.
- Exclusion verification: Navigate to an excluded page during a test session. Confirm no replay segment exists for that URL.
- SPA route capture: Perform a scripted navigation across 3–4 routes. In the dashboard, verify each route appears as a separate pageview in the session timeline.
- Payload size: Inspect a
collectrequest payload (Network → Payload). Ensure it stays under ~50 KB per batch for typical pages; investigate if larger.
Limitations and Ongoing Checks
- Retention, regional storage, masking defaults, and quota behavior are version- and plan-sensitive. Confirm current settings in the Clarity dashboard before each rollout phase.
- New form fields or third-party widgets may introduce unmasked sensitive data. Add a CI step that greps for
inputwithoutdata-clarity-maskon pages marked sensitive. - Consent rates vary by region; sample bias may skew replay representativeness. Pair with heatmaps for full-population aggregates.
- Clarity does not provide a programmatic API to delete already-captured sessions. If a compliance issue is discovered, you must contact support or disable the project.
Practical Way to Confirm the Result
After deploying the consent-gated snippet, run a 24-hour canary on 5% of traffic (via feature flag or CDN routing). In the Clarity dashboard, verify:
- Session count matches expected consent rate.
- No sessions contain unmasked PII (spot-check 10 replays).
- SPA routes appear correctly in the session timeline.
- Average script load time and payload size stay within budget.
If all checks pass, increase rollout. If any fail, disable the feature flag, adjust masking/exclusions, and re-test.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.