TL;DR: Load Microsoft Clarity on the visitor's first interaction instead of in the page head. On clickwerxs.com, loading it right after the page loaded cost us our mobile Lighthouse gate (0.89 median against a 0.90 floor). Loading on interaction passed, because a default Lighthouse run never interacts with the page. The price: a visitor who leaves within 15 seconds without scrolling, tapping, typing or moving a pointer is never recorded.
The one-sentence answer: Microsoft Clarity is light, but it is not free in a lab audit, so inject it after the first real interaction, allow every Clarity subdomain in your Content Security Policy, and then confirm three network requests before you trust a single recording.
We installed Clarity on clickwerxs.com on August 13, 2026. It took three deploys in one afternoon to get it right, and two of them failed in ways Microsoft's setup page doesn't mention.
The first deploy recorded nothing. The second recorded everything and failed our performance gate. The third is what runs today.
This is the how-to we wish we'd had, with the numbers from our own CI logs. If you want the tour of what Clarity does first, start with what Microsoft Clarity is and why every business site should run it.
Prerequisites
You need four things before you start:
- A Clarity project and its ID. Sign up at clarity.microsoft.com, add your site, and copy the project ID from Settings. Ours is a 10-character string.
- Access to your site's code or tag manager. Microsoft's setup guide says to "paste it into the
<head>section of your website," which is exactly the step this post changes. - A way to measure before and after. A PageSpeed Insights report works. A Lighthouse CI gate works better, because a single run is noisy and the median of five is steadier.
- Your current Content Security Policy, if you have one. Check your response headers for
Content-Security-Policy. If it's there, Step 3 is not optional.
Why does a free analytics script cost PageSpeed points at all?
Lighthouse measures the page loading in a lab. Total Blocking Time, the metric third-party scripts hurt most, "measures the total amount of time that a page is blocked from responding to user input," per Chrome's Lighthouse documentation, and it carries 30% of the Lighthouse 10 performance score.
Microsoft's own position is that Clarity barely registers. Its 2021 performance post says "Clarity's code is asynchronous and therefore designed to have a very low impact on page load time," and reports 0 ms of blocking time across five test sites. The same post adds: "we cannot guarantee your site will not be affected in any way."
Our experience landed in that second sentence. Microsoft describes recordings as "step-by-step visual reconstructions by capturing the HTML and user actions," so the script has real work to do as soon as it starts. When our idle-scheduled load ran, it ran inside the window Lighthouse was timing.
Step 1: Gate the tag to your production domain
Before you think about timing, stop Clarity from recording your preview deploys and your laptop.
Without a gate, a localhost session or a staging deploy lands in the same project as real visitors, and we didn't want to rely on filtering those out later. We check window.location.hostname against a list of two production hosts (the apex and www) and return early for anything else.
If it fails: if you're on a site builder with no staging environment, skip this step and use Clarity's IP blocking instead: Settings, then IP blocking, then Block IP address, and tick "Block my current IP." Microsoft notes it supports IPv4 only, not VPN or dynamic addresses, and takes about 15 minutes to apply. It won't catch preview URLs, but it keeps your office connection out.
Step 2: Load Clarity on the first interaction, not on page load
Here is the sequence we actually tested, from the CI logs of August 13, 2026. Our gate runs Lighthouse five times per URL on mobile and asserts the median performance score is at least 0.90.
| Deploy | How Clarity loaded | Did Clarity run? | Gate result |
|---|---|---|---|
| 1 | Idle after load | No, blocked by our CSP | Passed |
| 2 | Idle after load | Yes | Failed: 0.89 median vs 0.90 |
| 3 | First user interaction, 15s fallback | Not expected during the audit (confirmed in a September 26 run) | Passed |
Deploy 1 passing meant nothing, because the tag never executed (Step 3 explains why). Deploy 2 was the first honest measurement, and it failed by one point.
Our idle-scheduled load still ran inside the window Lighthouse was timing, and running work extends the window TBT is measured against.
Interaction-based loading sidesteps that, because a default Lighthouse navigation doesn't scroll, tap or type. (A very slow audit could still outlast the 15-second fallback.) We ran Lighthouse against the live homepage on September 26, 2026: 61 network requests, zero of them to any clarity.ms host, and a 0.94 performance score.
This is the loader, reduced to plain JavaScript. Replace YOUR_PROJECT_ID:
<script>
(function () {
var hosts = ["example.com", "www.example.com"];
if (hosts.indexOf(location.hostname) === -1) return;
window.clarity = window.clarity || function () {
(window.clarity.q = window.clarity.q || []).push(arguments);
};
var done = false;
var timer;
var events = ["pointerdown", "pointermove", "keydown", "scroll", "touchstart", "wheel"];
function inject() {
if (done) return;
done = true;
events.forEach(function (e) { removeEventListener(e, inject); });
clearTimeout(timer);
var s = document.createElement("script");
s.async = true;
s.src = "https://www.clarity.ms/tag/YOUR_PROJECT_ID";
document.head.appendChild(s);
}
events.forEach(function (e) { addEventListener(e, inject, { once: true, passive: true }); });
timer = setTimeout(inject, 15000);
})();
</script>
Three details matter. The window.clarity stub is copied from Microsoft's own snippet and defined before anything else, so a clarity() call your site makes before the library arrives waits in a queue instead of throwing an error. (Our first draft of this loader created the stub inside inject(), and a test page threw "window.clarity is not a function" until we moved it.) The listeners are passive, so they never delay scrolling. The 15-second fallback catches the reader who sits on one page without moving the mouse.
The tradeoff, stated plainly: a visitor who leaves within 15 seconds without scrolling, tapping, typing or moving a pointer is never recorded. Their replay would have been a still frame. Google Analytics still counts the visit.
If it fails: if your gate still fails with Clarity deferred, Clarity is probably not your main problem. Remove the loader entirely, run the audit five times, and compare medians. If the score doesn't move, look at your other third-party tags first.
Step 3: Allow every Clarity subdomain in your Content Security Policy
This is the step that silently broke our first deploy. Our CSP had no Clarity entry, so the browser refused the tag on every production page view. Nothing on the site looked broken, and our policy has no violation reporting configured, so a blocked script only shows up in the visitor's own browser console. The fix shipped 17 minutes later, in the next deploy.
Microsoft's CSP guide tells you to add Clarity to default-src, with this example: default-src 'self' https://*.clarity.ms https://c.bing.com 'unsafe-inline';
That works only if your policy has no script-src or connect-src of its own. MDN is explicit: default-src is a fallback, and "if there are other directives specified, default-src does not influence them." If your CSP declares script-src or connect-src, as ours does, adding Clarity to default-src alone does nothing for those requests.
What we shipped instead:
script-srcgetshttps://*.clarity.msconnect-srcgetshttps://*.clarity.msandhttps://c.bing.com
Use the wildcard. When we checked the live site on September 26, 2026, one page view touched three different Clarity hosts: the tag from www.clarity.ms, the library from scripts.clarity.ms, and the data upload to z.clarity.ms. Allowing only www blocks the other two.
If it fails: open DevTools, go to the Console, and look for "Refused to load the script" or "Refused to connect." The message names the blocked URL and the directive that blocked it. Add that host pattern to that directive, redeploy, and check again.
Step 4: Verify the install in the Network tab
Don't wait for the dashboard to fill. Check the requests yourself, in this order:
- Open your live site in a normal browser window with DevTools on the Network tab. Filter by
clarity. - Load the page and keep your pointer off it for three seconds. With the interaction loader you should see nothing.
- Scroll once. Three things should appear: the tag request (
/tag/your-id) with status 200,clarity.jswith status 200, and one or more POST requests to/collect.
Microsoft's verification step is to "see POST requests to https://www.clarity.ms/collect while interacting with your site." On our site those POSTs go to z.clarity.ms/collect and return 204, which is a success with no body. Don't expect the www host specifically.
If it fails: no tag request at all means your loader isn't running (check the hostname list). A tag request that fails means CSP (Step 3). A tag that loads but no /collect means connect-src. Microsoft's installation troubleshooting page also says to "refresh the page after a few minutes" before assuming the worst.
How do you install Clarity on WordPress, Shopify, Wix or Squarespace?
Microsoft documents a native route for each:
- WordPress: the "Microsoft Clarity" plugin, from Plugins, then Add new plugin.
- Shopify: the "Microsoft Clarity: AI Insights" app from the Shopify App Store. Microsoft's Shopify guide says to "allow a few hours for your dashboard to populate with data."
- Wix: Apps, then App Market, then Microsoft Clarity.
- Squarespace: Settings, then Advanced, then Code Injection, pasting the tag into the Header field. This needs a plan that allows custom code.
- Google Tag Manager: Microsoft lists three options, including an official community template and a Custom HTML tag.
The honest limit: the plugin and app routes load Clarity on their own schedule, and we found no setting in them for interaction loading. On Squarespace and GTM you can paste the loader from Step 2 instead of the default snippet. If you're on a hosted plan with a 90+ mobile score you care about, that's the version to use.
Where this fails
Lab score isn't field experience. Clarity has its own Performance panel built from real visitors, and Microsoft's documentation says the LCP, INP and CLS it shows "are the 75th percentile." Ours, for the 30 days to September 26, 2026, reads 69 out of 100 from 22 page views, with an Interaction to Next Paint shown as 1K ms. Google's web.dev guidance calls anything above 500 ms poor.

That's the site whose homepage scored 0.94 in the lab the same day. The two numbers measure different things: one lab load of one page against 30 days of real visits across every page.
Here is the uncomfortable part. Interaction loading moves Clarity's startup work to the moment right after a visitor's first interaction, and INP measures responsiveness to interactions. We haven't isolated how much of that figure is Clarity, and 22 page views is too small a sample to try. Web.dev puts it directly: TBT "may be a reasonable proxy metric for INP, but it's not a substitute for INP in and of itself."
So the method in this post protects your Lighthouse score. It doesn't prove your visitors feel nothing. Watch the INP number in your own Clarity dashboard for a month after you ship this, and if it degrades, test with Clarity removed for a week.
One Lighthouse run is noise. Lighthouse records a benchmark index for the machine it runs on. Our passing run's index was higher on four of its five runs than on the failing run, so part of the difference may be the hardware. The September 26 run supports the mechanism more directly: zero Clarity requests during the audit.
Consent changes what Clarity reports. For visitors in the EEA, UK and Switzerland, Microsoft began enforcing consent signal requirements on October 31, 2025, and says a valid signal is "required to ensure full functionality." Without one, Clarity changes its reporting: "Sessions are counted as pageviews," and no visitor is counted as returning. If you serve those regions, pass the visitor's choice through Clarity's consent API. Whether you may load it at all before consent is a legal question for your jurisdiction.
What does success look like?
You're done when all four are true:
- Five-run median mobile Lighthouse score unchanged (within a point) from before the install
- No
clarity.msrequests in the Network tab before your first interaction - Tag 200,
clarity.js200 and/collectsuccess after one scroll - Sessions appearing in the Clarity dashboard within a few hours
Then the useful part begins, which is choosing which recordings to watch. That's the next post in this series: how to watch 20 session recordings and learn something.
If you'd rather have this installed, tested and gated for you, our web design team builds sites with the performance budget written into the deploy pipeline, the same way we built our own. Tell us what you're running.
Frequently Asked Questions
Does Clarity use cookies?
Yes. Microsoft's FAQ notes that "any third-party cookies used by Clarity are to support operational purposes like advertising." If you run a consent banner, map Clarity to both analytics and advertising storage, and pass the visitor's choice through Microsoft's Consent API (the current version is consentv2, which takes separate ad storage and analytics storage signals).
Will the interaction loader break Clarity's custom tags or identify calls?
No, provided the stub runs before your calls. The queue stub collects every clarity() call made before the library arrives and hands them over when it loads. Place the loader above any code that calls clarity("set", ...).
Can I use this loader for other heavy tags?
The pattern works for any script that only matters once a person is engaging: chat widgets are the obvious candidate. It's wrong for anything that must measure the page load itself, such as a real user monitoring library, because it would miss the load it exists to measure.
Can I run Clarity alongside another session-replay tool?
We wouldn't. Two replay scripts means two page snapshots competing for the same main thread, which is the exact cost this post is about. Pick one, run it for a month, and decide on data.
Sources
- Microsoft Learn, "Set up Clarity": "Copy the code and paste it into the
<head>section of your website or web app"; verification: "See POST requests to https://www.clarity.ms/collect while interacting with your site." learn.microsoft.com (page dated 2025-08-08, retrieved 2026-09-26) - Microsoft Learn, "Clarity CSP": "default-src 'self' https://*.clarity.ms https://c.bing.com 'unsafe-inline';" learn.microsoft.com (page dated 2025-05-14, retrieved 2026-09-26)
- MDN, "CSP: default-src": "If there are other directives specified, default-src does not influence them." developer.mozilla.org (last modified 2025-07-04, retrieved 2026-09-26)
- Microsoft Clarity blog, "Does Clarity affect website performance?", Clarity Staff, November 23, 2021: asynchronous loading, 0 ms TBT across five test sites, "we cannot guarantee your site will not be affected in any way." Legacy benchmark. clarity.microsoft.com (retrieved 2026-09-26)
- Chrome for Developers, "Total Blocking Time": TBT definition developer.chrome.com; "Lighthouse performance scoring": TBT weighted 30% in Lighthouse 10 developer.chrome.com (both retrieved 2026-09-26)
- web.dev, "Interaction to Next Paint (INP)": thresholds of 200 ms and 500 ms; TBT "may be a reasonable proxy metric for INP, but it's not a substitute." web.dev (updated 2025-09-02, retrieved 2026-09-26)
- Microsoft Learn, "Performance" widget: "LCP, INP, and CLS displayed here are the 75th percentile." learn.microsoft.com (page dated 2025-11-06, retrieved 2026-09-26)
- Microsoft Learn, "Changes to Clarity reporting without cookie consent": enforcement for EEA, UK and Switzerland from October 31, 2025; "Sessions are counted as pageviews" without consent. learn.microsoft.com (retrieved 2026-09-26)
- Microsoft Learn, third-party integrations (WordPress, Shopify, Wix, Squarespace, Google Tag Manager). learn.microsoft.com (retrieved 2026-09-26)
- Microsoft Learn, Clarity FAQ (third-party cookies) learn.microsoft.com (page dated 2026-09-21), Consent API v2 learn.microsoft.com, IP blocking learn.microsoft.com, Recordings overview ("visual reconstructions by capturing the HTML") learn.microsoft.com, Installation troubleshooting learn.microsoft.com. All retrieved 2026-09-26.
- ClickWerxs operator data: Lighthouse CI gate logs for three production deploys on August 13, 2026 (median of five mobile runs, 0.90 floor); Lighthouse 12 run and live network capture on clickwerxs.com, September 26, 2026; loader snippet tested on a local page September 26, 2026 (queued call before interaction, single tag injection on first scroll, fallback firing between 10 and 17 seconds, zero Clarity requests in a Lighthouse run); Clarity Performance panel for clickwerxs.com, 30 days to September 26, 2026.
Kaleb Dickhaut — Founder, ClickWerxs. Kaleb built ClickWerxs from the ground up, from payment processing ISO to the Command Center platform to the AI SEO methodology the blog runs on. He has onboarded hundreds of small businesses onto payment and CRM systems. linkedin.com/in/kaleb-dickhaut
Product details in this post reflect Microsoft's documentation as of September 26, 2026 and change often. ClickWerxs is not affiliated with Microsoft and earns revenue from the web design services described. This post reflects publicly available regulatory information as of the publication date. Regulations vary by jurisdiction and change frequently. This is not legal advice. Consult qualified legal counsel before making compliance decisions for your business.
