NextJS 13 with app router how to add Microsoft Clarity script to head?

1.2k Views Asked by At

I'm trying to add Microsoft Clarity to my website. I've tried to add it using next/head and next/script but It won't let me the use script in the head. When I implement it like below script is not added to head and clarity can not properly show me what the users really see.

Edit: I tried to use strategy="afterInteractive" that did not work, too. Script not in head.

Edit2: I added pages/_document.js as stated in docs. Script not loading. Docs NextJS

I'm moving my website from Nuxt3 to NextJS. In Nuxt3 I managed to add a script to head section of the app but I couldn't find a way to do same in NextJS 13 using app router. Here is the code for reference.

export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html lang="en">
      <head>
        <Script
          id="ms-clarity"
          dangerouslySetInnerHTML={{
            __html: `(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", "keyyyy");
        `,
          }}
        />
      </head>
      <body className={inter.className}>{children}</body>
    </html >
  )
}

2

There are 2 best solutions below

0
EpicWerf On

For anyone else curious, I got this to work by putting the Script tag outside of the Head tag, and putting the function inside of the Script tag.

This is in my root layout page (src/app/layout.tsx)

const RootLayout = async ({ children }: React.PropsWithChildren) => {
  return (
    <html lang="en">
      {/* Clarity Script */}
      <Script strategy="lazyOnload" id="clarity-script">
        {`
          (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", "keyyyyyy");
        `}
      </Script>

      <body>
        <main>{children}</main>
      </body>
    </html>
  );
};

export default RootLayout;
0
Rafael Carlos On

Another option :

export  const Clarity =()=>{
  return(
    <script
  dangerouslySetInnerHTML={{
    __html: `
        (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", "XXXXXXXXX");`,
  }}
/>
)
}