Why Track User Behavior?
Understanding how users interact with your website is crucial for improving the user experience. Behavior analytics tools help identify friction points, optimize conversions, and provide insights into how users navigate your application.
Why Microsoft Clarity?
Microsoft Clarity is a free behavior analytics tool that offers:
✅ Heatmaps – Visualize where users click and scroll.
✅ Session Recordings – Replay user sessions to understand their journey.
✅ Insights – Identify pain points and engagement metrics.
✅ Google Analytics Integration – Combine behavioral data with standard analytics.
In this guide, we’ll integrate Microsoft Clarity into a Next.js app and ensure it runs efficiently without affecting server-side rendering (SSR). Let’s get started!
Video of Clarity dashboard
1. Create a next app
If you don’t have an existing Next.js project, create one using:
npx create-next-app ms-clarity-example
2. Install Microsoft Clarity
Install the Clarity package using:
npm install @microsoft/clarity
3. Get Your Clarity Project ID
2.1. Create a project via
https://clarity.microsoft.com/
2.2. Navigate to Settings → Overview and copy the Project ID.
4. Initializing Clarity in Next.js
To start tracking user sessions, we need to initialize Clarity using:
Clarity.init();
🚨 The Catch: Run Clarity on the Client Side Only
- Clarity should not run on the server side, as it relies on window.
- We must use useEffect to ensure it runs only in the browser.
- The best place to initialize Clarity is in the top-level layout.tsx file.
❌ Initial Approach: Adding it Directly in RootLayout.tsx
"use client"
/* Rest of the code */
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
useEffect(() => {
if (typeof window !== "undefined") {
Clarity.init(process.env.NEXT_PUBLIC_CLARITY_ID!);
}
}, []);
/* Rest of the code */
⚠️ Problem: RootLayout Becomes a Client Component
By adding "use client"
, we force RootLayout
to be client-rendered, preventing Next.js from utilizing SSR and static generation. Instead, we should move Clarity initialization to a separate component.
Hook vs a component
Hook
If the logic is moved to a hook we have the same problem RootLayout
needs to be a client component
.
import Clarity from "@microsoft/clarity";
import { useEffect } from "react";
export default function useMsClarity() {
useEffect(() => {
if (typeof window !== "undefined") {
Clarity.init(process.env.NEXT_PUBLIC_CLARITY_ID!);
}
}, []);
}
// Rootlayout.tsx
"use client"
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
// use hook
useMsClarity();
Component
Lets create a client component to hold the logic
"use client";
import Clarity from "@microsoft/clarity";
import { useEffect } from "react";
export default function useMsClarity() {
useEffect(() => {
if (typeof window !== "undefined") {
Clarity.init();
}
}, []);
return null;
}
Use the component in root layout.
import type { Metadata } from "next";
import { Inter } from "next/font/google";
import "./globals.css";
import BaseLayout from "./ui/layouts/BaseLayout";
import ClarityInit from "./ui/analytics/clarity-init";
const inter = Inter({ subsets: ["latin"] });
export const metadata: Metadata = {
title: "MS clarity test",
description: "MS clarity test",
};
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
{children}
);
}
Enter fullscreen mode
Exit fullscreen mode
By moving the logic to a separate component (ClarityInit), we avoid making RootLayout a client component, allowing the rest of the app to benefit from Server-Side Rendering (SSR).
6. Store the Clarity Project ID Securely
finally move the clarity-project-id to an env variable to make sure that it doe not pushed to version control system.
Clarity.init(process.env.NEXT_PUBLIC_CLARITY_ID!);
Enter fullscreen mode
Exit fullscreen mode
Note
The NEXT_PUBLIC_ prefix is needed so that nextjs can read the env variable.add it to .env file as well
NEXT_PUBLIC_CLARITY_ID=
Enter fullscreen mode
Exit fullscreen mode
Ms-clarity will start to collect sessions and you can see them in the dashboard.git hub link with code example.
https://github.com/chamupathi/ms-clarity