How to add Google Analytics 4 to Nextjs

How to add Google Analytics 4 to Nextjs
Photo by Stephen Phillips - Hostreviews.co.uk / Unsplash

We'll use the "with-google-analytics" example provided by the Nextjs team. I created this post to help people who might overlook the example (Like me 😢).

touch lib/gtag.js

lib is stand for library in short.

add the code:

export const GA_TRACKING_ID = "G-1234567890";

// https://developers.google.com/analytics/devguides/collection/gtagjs/pages
export const pageview = (url) => {
  window.gtag('config', GA_TRACKING_ID, {
    page_path: url,
  })
}

// https://developers.google.com/analytics/devguides/collection/gtagjs/events
export const event = ({ action, category, label, value }) => {
  window.gtag('event', action, {
    event_category: category,
    event_label: label,
    value: value,
  })
}

How to find your Google Analytics 4's ID?

After creating your new Google Analytics 4's property:

  1. Click "Admin" (the gear icon at the bottom left-hand corner)
  2. Click "Data Streams"
  3. Click the property you just created
  4. Find the "Measurement ID"

Open ./lib/gtag.js

Replace G-1234567890 with your "Measurement ID"

📝 You can also add the "GA_TRACKING_ID" to the environment variable:

Create the file on the root directory:

touch .env.local

Add the code:

NEXT_PUBLIC_GA_ID=G-1234567890

Since this GA_ID is easy to discover with the browser and not even a secret key in the ".env.local" file, I'll just add it to the "gtag.js" file as above.

You choose which option you work best for you.

Add Google Analytics 4 to _app.js

Open ./pages/_app.js

import { useEffect } from 'react'
import { useRouter } from 'next/router'
import * as gtag from '../lib/gtag'
  const router = useRouter()
  useEffect(() => {
    const handleRouteChange = (url) => {
      gtag.pageview(url)
    }
    router.events.on('routeChangeComplete', handleRouteChange)
    return () => {
      router.events.off('routeChangeComplete', handleRouteChange)
    }
  }, [router.events])

Final result of the code:

import { useEffect } from 'react'
import { useRouter } from 'next/router'
import * as gtag from '../lib/gtag'

const App = ({ Component, pageProps }) => {
  const router = useRouter()
  useEffect(() => {
    const handleRouteChange = (url) => {
      gtag.pageview(url)
    }
    router.events.on('routeChangeComplete', handleRouteChange)
    return () => {
      router.events.off('routeChangeComplete', handleRouteChange)
    }
  }, [router.events])

  return <Component {...pageProps} />
}

export default App

Add Google Analytics 4 to _document.js

Without adding the Google Analytics 4 code to _document.js, your Google Analytics will still collect data, but it's incomplete. Some data might be missing.

Open ./pages/_document.js

import { GA_TRACKING_ID } from '../lib/gtag'

Add the code:

 {/* Global Site Tag (gtag.js) - Google Analytics */}
          <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,
            });
          `,
            }}
          />

Final result of the code:

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

import { GA_TRACKING_ID } from '../lib/gtag'

export default class MyDocument extends Document {
  render() {
    return (
      <Html>
        <Head>
          {/* Global Site Tag (gtag.js) - Google Analytics */}
          <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>
    )
  }
}

Feel free to tweet me if you have any feedback, improvement, suggestion or error.