Add tracker to Next.js App

Here's a quick example of how you can add an external analytics JavaScript tracking snippet in your Next.js application:

Write this in your _document.tsx file. Create it in your pages directory if it doesn't exist.

If you are using the new app routing, copy the <head> section into /app/layout.tsx.

Note!! - This was the tracking code as of version 6.4.0.

Please update it to match the tracking code given to you in the UXWizz dashboard.

Set your own dashboard URL dashboardURL constant.

Next.js UXWizz snippet in _document.tsx

import { Html, Head, Main, NextScript } from 'next/document';

const dashboardURL = 'https://your.uxwizz.com/server';
const trackedDomain = 'yourappdomain.com';

export default class MyDocument extends Document {
  render() {
    return (
      <Html>
        <Head>
          {/* UXWIZZ SNIPPET START */}
          {/* Global scope */}
          <script
            dangerouslySetInnerHTML={{
              __html: `UST_CT = [];UST = { s: Date.now(), addTag: function(tag) { UST_CT.push(tag) } };UST.addEvent = UST.addTag;`,
            }}
          />

          {/* vvv -- Only include this part to enable A/B tests -- vvv*/}
          <script
            dangerouslySetInnerHTML={{
              __html: `(function() {var ust_s = document.createElement('STYLE');ust_s.id = 'ust_body_style';
              ust_s.appendChild(document.createTextNode('body {opacity: 0}'));document.head.appendChild(ust_s);})();
              setTimeout(function(){ var el = document.getElementById('ust_body_style'); el && el.remove()}, 800);`,
            }}
          />
          <script src={`${dashboardURL}/ab/${trackedDomain}.ab.js?v=x.x.x`} defer />
          {/* ^^^ -- Only include this part to enable A/B tests -- ^^^*/}

          {/* Main UXWizz script */}
          <script src={`${dashboardURL}/ust.min.js?v=x.x.x`} async />
          {/* UXWIZZ SNIPPET END */}
        </Head>
        <body>
          <Main />
          <NextScript />
        </body>
      </Html >
    )
  }
}

Next.js UXWizz snippet in /app/layout.tsx

const dashboardURL = 'https://your.uxwizz.com/server';
const trackedDomain = 'yourappdomain.com';

...

export default function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode;
}>) {
  return (
    <html lang="en">
    
    
      <head>
        {/* UXWIZZ SNIPPET START */}
        {/* Global scope */}
        <script
          dangerouslySetInnerHTML={{
            __html: `UST_CT = [];UST = { s: Date.now(), addTag: function(tag) { UST_CT.push(tag) } };UST.addEvent = UST.addTag;`,
          }}
        />

        {/* vvv -- Only include this part to enable A/B tests -- vvv*/}
        <script
          dangerouslySetInnerHTML={{
            __html: `(function() {var ust_s = document.createElement('STYLE');ust_s.id = 'ust_body_style';
              ust_s.appendChild(document.createTextNode('body {opacity: 0}'));document.head.appendChild(ust_s);})();
              setTimeout(function(){ var el = document.getElementById('ust_body_style'); el && el.remove()}, 800);`,
          }}
        />
        <script src={`${dashboardURL}/ab/${trackedDomain}.ab.js?v=x.x.x`} defer />
        {/* ^^^ -- Only include this part to enable A/B tests -- ^^^*/}

        {/* Main UXWizz script */}
        <script src={`${dashboardURL}/ust.min.js?v=x.x.x`} async />
        {/* UXWIZZ SNIPPET END */}
      </head>
      
      
      <body>
        {children}
      </body>
    </html>
  );
}
...

This will only track the initial page as a pageview. To track all route changes, add this component:

UXWizzPageview.tsx

'use client';

import { usePathname, useSearchParams } from "next/navigation";
import { useEffect, useRef } from "react";

export default function UXWizzPageview() {
    const pathname = usePathname();
    const searchParams = useSearchParams();
    const isInitialLoad = useRef(true);

    useEffect(() => {
        if (isInitialLoad.current) {
            isInitialLoad.current = false
            return;
        };
        if (typeof window === 'undefined') return;
        const ust = (window as typeof window & { UST: { trackNewPage: () => void } })['UST'];
        if (!ust || !ust.trackNewPage) return;
        ust.trackNewPage(); // Call on route change, but not on initial load
    }, [pathname, searchParams]);

    return null;
}

You can then import this in the body section of layout.tsx:

...

import dynamic from 'next/dynamic';
const UXWizzPageview = dynamic(() => import('./UXWizzPageview'), { ssr: false });
...
...
...
      <body>
        <UXWizzPageview />
        {children}
      </body>
...

If you don't use TypeScript, you can simply remove the typings replace this line:

const ust = (window as typeof window & { UST: { trackNewPage: () => void } })['UST'];

with

const ust = window['UST'];

Last updated