Record Microsoft Clarity sessions only with the consent of your visitors
Microsoft Clarity belongs to the tracking category of TermsFeed Free Cookie Consent: tag the Clarity code or load it untagged, and grant consent with the Clarity consentv2 command. With the tagged code, Clarity receives nothing before consent. The untagged code, with the Clarity "Cookies" setting turned off, lets Clarity record visitors without cookies until they accept.
Clarity enforces consent signals for page visits from the European Economic Area (EEA), the UK, and Switzerland since 31 October 2025, according to the Microsoft Clarity documentation. Without a granted signal, Clarity assigns a new ID to each page view and does not store cookies, so each page of a visit shows as a separate session. Both approaches send Clarity the signal it needs.
Before you start, have the Cookie Consent code from the TermsFeed generator on your pages, and access to your Clarity project.
Approach 1: Tag the Clarity code with tracking
Tag the Clarity code with tracking, so Clarity loads only after the visitor accepts tracking, then grant Clarity consent from the scripts_specific_loaded callback. The grant matters for EEA, UK, and Swiss visitors.
Copy the Clarity tracking code from your Clarity project: select Settings, then Setup, then Get tracking code, according to the Microsoft Learn page How to setup Clarity manually. Microsoft shows the code only inside Clarity. Replace its opening <script> tag with this tagged opening tag, and keep the JavaScript and the closing </script> tag unchanged.
<script type="text/plain" data-cookie-consent="tracking">
Place the tagged code in <head>, as Microsoft asks for the Clarity code. Learn how tagged scripts run in Block Scripts Until Consent.
Add a scripts_specific_loaded callback with callbacks_force: true to run(), so Clarity receives a consent signal and sets its cookies. The callback grants analytics_Storage with clarity('consentv2', ...) once the tagged code runs, and ad_Storage once the visitor accepts targeting.
Clarity requires both keys in every consentv2 call, so the callback keeps the 2 values in one object and sends the whole object each time. Copy the callbacks and callbacks_force options into the run() call that the TermsFeed generator wrote.
"callbacks": {
"scripts_specific_loaded": function (level) {
window.clarityConsent = window.clarityConsent || {
ad_Storage: 'denied',
analytics_Storage: 'denied'
};
switch (level) {
case 'tracking':
if (typeof window.clarity === 'function') {
window.clarityConsent.analytics_Storage = 'granted';
window.clarity('consentv2', window.clarityConsent);
}
break;
case 'targeting':
if (typeof window.clarity === 'function') {
window.clarityConsent.ad_Storage = 'granted';
window.clarity('consentv2', window.clarityConsent);
}
break;
}
}
},
"callbacks_force": true
Keep callbacks_force: true. Without it, scripts_specific_loaded runs only for categories that have tagged scripts, so Clarity does not get a grant for a category with no tagged script on the page. An example is targeting on a page with no tagged ad script. With callbacks_force, the callback runs for each accepted category on every page load and right after the visitor accepts. Read when the callback runs, and why it needs the option, in When scripts_specific_loaded Needs callbacks_force.
The callback sends grants only. A visitor who turns tracking off does not get a grant from the next page load, and Cookie Consent does not delete _clck or _clsk cookies Clarity stored before. Copy the signal names for every vendor from Map Categories to Vendor Consent Signals.
A grant call carries the other Clarity key as denied until that key is granted too. Clarity therefore learns of a withdrawal only while the visitor still accepts the other Clarity category. Microsoft asks site owners to inform Clarity of every change in consent, according to the Microsoft Learn page Consent Mode. The Clarity consent API reference says Clarity deletes its cookies when a visitor rejects them, and that window.clarity('consent', false) erases them, but not that a denied consentv2 value does. After a withdrawal, delete the _clck and _clsk cookies from the callback in Rejecting Does Not Delete Cookies Already Set, which acts on each page load while tracking is off. The tagged Clarity code keeps running on the page of a withdrawal, so call window.clarity('consent', false) there too, inside a typeof window.clarity check.
Approach 2: Load Clarity untagged with cookies turned off
Load the Clarity code untagged, turn off the Clarity cookie setting, and grant consent with consentv2 from the scripts_specific_loaded callback. Clarity then records every visitor without cookies until the visitor accepts tracking, and joins the pages of a visit into one session after that.
Turn off cookies in Clarity first. Open your Clarity project, select Settings, then Setup, and turn off Cookies under Advanced settings. Clarity then waits for a consent signal from every visitor, wherever the visitor is. With the setting on, Clarity stores cookies at once for visitors outside the EEA, the UK, and Switzerland.
Paste the Clarity tracking code from Get tracking code into <head> unchanged, as Microsoft asks.
Copy the callbacks and callbacks_force options of Approach 1 into the run() call that the TermsFeed generator wrote. The callback grants analytics_Storage once the visitor accepts tracking, and Clarity starts storing its cookies from that moment. To erase the Clarity cookies after a withdrawal, call window.clarity('consent', false) from a user_consent_saved callback when reason is 'choice' and details.tracking is false. The callback makes the call when a visitor declines too, and Microsoft says the call stops Clarity recording that visitor until the next grant, on that page only.
How to verify that Microsoft Clarity waits for consent
The checks assume express consent with page_load_consent_levels left out or at the generator value ["strictly-necessary"], and the "I decline" button shown. Publish the change and clear any page cache before the check. Check the Network tab for Clarity requests and the Application tab for the _clck and _clsk cookies, before and after a click on the "I agree" button. Run this console check from the Clarity documentation to print the consent state Clarity holds.
clarity('metadata', function (d, upgrade, consent) {
console.log('consentStatus:', consent);
}, false, true, true);
Close every private window, then run the check in a new one, which does not hold a saved answer. Compare the results before the answer, after accepting, and after declining.
- Open your site in that window of Chrome, open DevTools, and select the Network tab.
- Type
clarity.msin the filter box and reload. With Approach 1, no request appears while the consent banner shows. With Approach 2,collectrequests to aclarity.mssubdomain appear, which is Clarity recording without cookies. - Select the Application tab and open Cookies. Your site does not list a
_clckor_clskcookie before the answer, in both approaches. - Click the "I agree" button. The
_clckand_clskcookies appear, and the Network tab showscollectrequests to aclarity.mssubdomain. - Select the Console tab and run the Clarity console check. After the click on the "I agree" button, the console check prints
consentStatus:with an object whose analytics storage key reads"GRANTED". - Close every private window and open a new one. Open DevTools, type
clarity.msin the Network filter, load your site, and click the "I decline" button. No_clckor_clskcookie appears, and with Approach 1 theclarity.msfilter stays empty.
Cookies Microsoft Clarity sets
Clarity stores 2 first-party cookies on your domain and reads third-party cookies on Microsoft domains, according to the Clarity cookie list. List them in your Cookies Policy under tracking cookies.
| Cookie | Party | Purpose |
|---|---|---|
_clck |
First-party | Keeps the Clarity user ID and preferences for your site |
_clsk |
First-party | Joins the page views of a visitor into one session recording |
CLID, MUID, ANONCHK, MR, SM |
Third-party, Microsoft domains | Identify the browser across Microsoft services and sites that use Clarity |
Microsoft names the cookies and their purposes in Clarity Cookies, without their lifetimes. Read each lifetime in the Application tab of Chrome DevTools, in the Expires / Max-Age column of the cookie list.
Common mistakes with Microsoft Clarity
Find each mistake in your setup from the Application tab, the console check, or the page source.
- The Clarity cookie setting stays on in Approach 2. The Application tab then lists
_clckbefore the answer for a visitor outside the EEA, the UK, and Switzerland, and Settings > Setup shows Cookies turned on. Turn off Cookies in the Clarity setup settings. - Approach 1 has no
scripts_specific_loadedcallback. For a visitor from the EEA, the UK, or Switzerland, the console check does not show an analytics storage key that reads"GRANTED"after you accept. Add the callback torun(). callbacks_forceis missing in Approach 2. On a page with no script taggedtracking, the Application tab does not list a_clckcookie after you click the "I agree" button. Add"callbacks_force": truetorun().- A platform integration loads a second copy of Clarity. The Clarity plugins for WordPress, Shopify, and Wix, and a Clarity tag in a tag manager container, add an untagged copy. With Approach 1, requests to
clarity.msappear before you answer. Search the page source and your tag manager container forclarity.msto find each copy. Remove the extra copy and keep yours. - The keys are spelled with a lowercase S. The console check does not show
"GRANTED"after you accept. Clarity writesad_Storageandanalytics_Storagewith a capital S, unlike the Google signals. Read the keys your callback passes toconsentv2, and look for a lowercase s. Copy the keys from the callback in Approach 1. - You grant consent with the older
clarity('consent')command. Microsoft replaced it withconsentv2and plans to deprecate it. Search your code forclarity('consent')calls withoutfalse, which grant consent. Sendconsentv2for the grant, and keepclarity('consent', false)for a withdrawal.