How to use google analytics with next.js app? How to use google analytics with next.js app? reactjs reactjs

How to use google analytics with next.js app?


The accepted answer does not work. Instead, to correctly initialize gtag, do the following in _document.js or wherever you defined Head:

import { Head } from 'next/document';export default class MyDocument extends Document {  render() {    return (      // ...      <Head>        <script          async          src="https://www.googletagmanager.com/gtag/js?id=[Tracking ID]"        />        <script          dangerouslySetInnerHTML={{            __html: `              window.dataLayer = window.dataLayer || [];              function gtag(){dataLayer.push(arguments);}              gtag('js', new Date());              gtag('config', '[Tracking ID]', { page_path: window.location.pathname });            `,          }}        />      </Head>    );  }}

The above will track page views on page load. To track navigation add the following to _app.js:

import { useRouter } from 'next/router';export default const App = () => {  const router = useRouter();  const handleRouteChange = (url) => {    window.gtag('config', '[Tracking ID]', {      page_path: url,    });  };  useEffect(() => {    router.events.on('routeChangeComplete', handleRouteChange);    return () => {      router.events.off('routeChangeComplete', handleRouteChange);    };  }, [router.events]);  return (    // ...  );};

See also:


To setup Google analytics with NextJS using Typescript

I'm using below setup for my personal site (https://github.com/GorvGoyl/Personal-Site-Gourav.io) and it's working fine without any linting errors. Analytics is enabled only for production.

  • Create a Google analytics project and get Measurement ID.
  • In your NextJS project, create /lib/gtag.ts file and add your Google Measurement ID:
export const GA_TRACKING_ID = "<INSERT_TAG_ID>";// https://developers.google.com/analytics/devguides/collection/gtagjs/pagesexport const pageview = (url: URL): void => {  window.gtag("config", GA_TRACKING_ID, {    page_path: url,  });};type GTagEvent = {  action: string;  category: string;  label: string;  value: number;};// https://developers.google.com/analytics/devguides/collection/gtagjs/eventsexport const event = ({ action, category, label, value }: GTagEvent): void => {  window.gtag("event", action, {    event_category: category,    event_label: label,    value,  });};
  • Also install gtag types:
npm i -D @types/gtag.js
  • Create /pages/_document.tsx:
import Document, { Html, Head, Main, NextScript } from "next/document";import { GA_TRACKING_ID } from "../lib/gtag";const isProduction = process.env.NODE_ENV === "production";export default class MyDocument extends Document {  render(): JSX.Element {    return (      <Html>        <Head>          {/* enable analytics script only for production */}          {isProduction && (            <>              <script                async                src={`https://www.googletagmanager.com/gtag/js?id=${GA_TRACKING_ID}`}              />              <script                // eslint-disable-next-line react/no-danger                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>    );  }}
  • Create /pages/_app.tsx:
import { AppProps } from "next/app";import { useRouter } from "next/router";import { useEffect } from "react";import * as gtag from "../lib/gtag";const isProduction = process.env.NODE_ENV === "production";const App = ({ Component, pageProps }: AppProps): JSX.Element => {  const router = useRouter();  useEffect(() => {    const handleRouteChange = (url: URL) => {      /* invoke analytics function only for production */      if (isProduction) gtag.pageview(url);    };    router.events.on("routeChangeComplete", handleRouteChange);    return () => {      router.events.off("routeChangeComplete", handleRouteChange);    };  }, [router.events]);  // eslint-disable-next-line react/jsx-props-no-spreading  return <Component {...pageProps} />;};export default App;


In your _document.js you override the getInitialProps method. You can also override the render method. Simply add

  render() {    return (      <Html lang={this.props.lang || "en"}>        <Head>          <script            dangerouslySetInnerHTML={{              __html: `[google analytics tracking code here]`            }}          />        </Head>        <body>          <Main />          <NextScript />        </body>      </Html>    );  }

Make sure you import the required components:

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