Google Analytics with Next.js

Author : JaNakh Pon , August 15, 2021

Tags

How to add Google Analytics 📈 to Next.js site

We can add Google Analytics to Next.js in a few steps:

  1. Get a Google Analytics ID from your Google Account
  2. Create a helper file for Google Analytics functions
  3. Add Google Analytics Site tag (aka gtag) into your browser window & configure _app tracking
  4. Add custom functions to track custom events

Summary

Firstly, we need to get a Google Analytics ID and we can either set it as a constant variable or put it in .env file.

Secondly, we will create a new file for google analytics and put everything for GA such as pageview, event and GA_TRACKING_ID variable value.

And finally, we need to configure gtag in _document.ts with GA_TRACKING_ID as well as configure _app.ts to track pageviews and events.


Creating a .ts file for GA helper functions

Let's get started by creating an index.ts file under lib:

  > mkdir lib && cd lib && touch index.ts && cd ..
  > npm i -D @types/gtag.js

and lib/index.ts:

export const GA_TRACKING_ID = "";

export const pageview = (url: URL): void => {
  window.gtag("config", GA_TRACKING_ID, {
    page_path: url,
  });
};

export const event = ({ action, params }) => {
  window.gtag('event', action, params);
};

Configuration

Let's add gtag to _document.tsx:

import Document, { Html, Head, Main, NextScript } from 'next/document'
import { GA_TRACKING_ID } from '../lib'

export default class MyDocument extends Document {
  render() {
    return (
      <Html>
        <Head>
          <script
            async
            src={`https://www.googletagmanager.com/gtag/js?id=${GA_TRACKING_ID}`}
          />
          <script
            dangerouslySetInnerHTML={{
              __html: `
            window.dataLayer = window.dataLayer || [];
            function gtag(){dataLayer.push(arguments);}
            gtag('js', new Date());
            gtag('config', '${GA_TRACKING_ID}', {
              page_path: window.location.pathname,
            });
          `,
            }}
          />
        </Head>
        <body>
          <Main />
          <NextScript />
        </body>
      </Html>
    )
  }
}

And _app.tsx:

import type { AppProps } from "next/app";
import { useEffect } from 'react'
import { useRouter } from 'next/router'
import * as ga from '../lib'

function MyApp({ Component, pageProps }: AppProps) {
  const router = useRouter()
  useEffect(() => {
    const handleRouteChange = (url:URL) => {
      ga.pageview(url)
    }
    //When the component is mounted, subscribe to router changes
    //and log those page views
    router.events.on('routeChangeComplete', handleRouteChange)

    // If the component is unmounted, unsubscribe
    // from the event with the `off` method
    return () => {
      router.events.off('routeChangeComplete', handleRouteChange)
    }
  }, [router.events])
  return <Component {...pageProps} />
}
export default MyApp

Custom events

Let's add a custom event to track in index.tsx:

import type { NextPage } from 'next'
import Head from 'next/head'
import Image from 'next/image'
import * as ga from '../lib'
import styles from '../styles/Home.module.css'

const Home: NextPage = () => {
  const handleClick = () => {
    ga.event({
      action: "button click",
      params: {
        event_text: "I got clicked!"
      }
    })
  }
  return (
    <div className={styles.container}>
      <Head>
        <title>Create Next App</title>
        <meta name="description" content="Generated by create next app" />
        <link rel="icon" href="/favicon.ico" />
      </Head>

      <main className={styles.main}>
        <h1 className={styles.title}>
          <button onClick={() => handleClick}>Click me!!!</button>
        </h1>
      </main>

      <footer className={styles.footer}>
        <a
          href="https://vercel.com?utm_source=create-next-app&utm_medium=default-template&utm_campaign=create-next-app"
          target="_blank"
          rel="noopener noreferrer"
        >
          Powered by{' '}
          <span className={styles.logo}>
            <Image src="/vercel.svg" alt="Vercel Logo" width={72} height={16} />
          </span>
        </a>
      </footer>
    </div>
  )
}
export default Home

Ref article, Source Code.

Go Back.