How toAdd Google Analytics to Next.js
Published: 2022-08-26 14:01:27

The implementation is straightforward and doesn't require any third-party library.

you will need:

- a Next.Js project
- a Google Analytics account

1 Add your google analytics id to your project .env.local file.

First, start with creating a .env.local file where you will place your Google Analytics key.

`Tip: Check your .gitignore to make sure that you don't commit this file by accident. .env.local should have already been included by default in your Next.js project but check to make sure.`

```
NEXT_PUBLIC_GOOGLE_ANALYTICS=<Your_tracking_ID>
```

2 Inject Google Analytics tracking code into your project application.

Now that your key is set, you need to inject and configure Google Analytics' Global site tag (aka gtag) into your browser window.

To access the head element in your Next.js application, you need to create a custom _document.js file into your pages folder.

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

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

3 Custom functions to track pageviews and events.

Let's move on to the tracking piece of Google Analytics. In order to correctly track your user's behaviours, you will need to log page views and optionally, specific events triggered in your application.

Inside your lib/ga folder, create an index.js with two functions: one to log pageviews and the other events.

```
// log the pageview with their URL
export const pageview = (url) => {
  window.gtag('config', process.env.NEXT_PUBLIC_GOOGLE_ANALYTICS, {
    page_path: url,
  })
}

// log specific events happening.
export const event = ({ action, params }) => {
  window.gtag('event', action, params)
}
```

_lib/ga/index.js_

4 Log pageviews in your project app.

The simplest way to log pageviews in your Next.js app is to subscribe to your router and listen for the routeChangeComplete event.

To do so, go into your _app.js file and with useEffect, check for new events happening with your router. There are many types of events but we only care when users navigate to a new page successfully (routeChangeComplete).

```
import { useEffect } from 'react'
import { useRouter } from 'next/router'

import * as ga from '../lib/ga'

function MyApp({ Component, pageProps }) {
  const router = useRouter()

  useEffect(() => {
    const handleRouteChange = (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
```

5 Log specific events in your project app.

Now that our page views are tracked, you may be interested in logging specific events in your application. Here is a list of Google Analytics Default events.

```
import { useState } from 'react'

import * as ga from '../lib/ga'

export default function Home() {
  const [query, setQuery] = useState("");

  const search = () => {
    ga.event({
      action: "search",
      params : {
        search_term: query
      }
    })
  }

  return (
    <div>
        <div>
          <input type="text" onChange={(event) => setQuery(event.target.value)}></input>
        </div>
        <div>
        	<button onClick={() => search()}>Search</button>
        </div>
    </div>
  )
}
```