Home > References > SEO

Next js google tag manager: Using Google analytics in Nextjs

Last updated : June 19, 2021

Using Google tag manager with Next js is simple but needs some additional work. There are two ways to add Google tag manager to Next js. Both methods require a history change trigger on the Google tag manager console to track Next js internal page navigations.

  • Placing Google provided scripts on a shared layout page
  • Using react-gtm-module npm package

Google tag manager is inherently designed with traditional request-response based websites in mind. If you use client-side rendering technologies like React js or Next js to server-side render a client-side application, you may already have noticed that google tag manager will not work out of the box. But Google tag manager has a built-in solution for this.

Where to begin with google analytics in Next js?

So, you have designed a stunning single page application with seamless page transitions. Now it's time to integrate your website with google analytics. If you haven't already done so, head on to https://tagmanager.google.com to create an account. Upon account creation, you will be presented with two javascript tags to place as high in the <head> of the page and immediately after the opening <body> tag.

/*Google Tag Manager - as high in the <head> of the page*/
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','GTM-XXXXXXX');</script>
<!-- End Google Tag Manager -->
/*Google Tag Manager (noscript)*/
<!--immediately after the opening <body> tag-->
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-XXXXXXX"
height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
<!-- End Google Tag Manager (noscript) -->

Where to put the analytics script tags?

There are two ways to implement google tag manager in Next js. However, both methods require a History change trigger in the google tag manager console.

  • 1. Inserting gtm scripts in header and page (as suggested by Google)
  • 2. Using npm package react-gtm-module

Below we discuss both methods in detail. Ensure to implement only one of these methods to avoid duplicate gtm tags.

1. Inserting gtm scripts in header and page

Depending on your Next js app architecture, you can place the above scripts somewhere in _app.js, layout.js, or _document.js. Make sure to place it in a resource shared by every page in your application. If you have a _document.js, you can place the script in the <Head/> section of the _document.js. You can use the below script tag to insert scripts inline without creating additional javascript files. Ensure to place the <script> and <noscript> tags in the proper position.

<script dangerouslySetInnerHTML={{ __html: `(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','GTM-XXXXXXX');`}}></script>

Now place the page script at the beginning of the body tag. Ensure this is visible to every page in your application.

<noscript dangerouslySetInnerHTML={{ __html: `<iframe src="https://www.googletagmanager.com/ns.html?id=GTM-XXXXX"
height="0" width="0" style="display:none;visibility:hidden"></iframe>`}}></noscript>

The below example shows the scripts inserted in the _document.js file. You may select the script location based on your Next app architecture.

import Document, { Html, Head, Main, NextScript } from 'next/document'
class WebDocument extends Document {
  render() {
    return (
      <Html lang="en-US">
        <Head>
        <script dangerouslySetInnerHTML={{ __html: `(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
        new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
        j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
        'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
        })(window,document,'script','dataLayer','GTM-XXXXXXX');`}}></script>
        </Head>
        <body>
            <noscript dangerouslySetInnerHTML={{ __html: `<iframe src="https://www.googletagmanager.com/ns.html?id=GTM-XXXXX"
            height="0" width="0" style="display:none;visibility:hidden"></iframe>`}}></noscript>
          <Main/>
          <NextScript />
        </body>
      </Html>
    )
  }
}
export default WebDocument

We are not done yet. Please read on to configure History change trigger.

2. Using npm package react-gtm-module

Using react-gtm-module is the easiest and cleanest way to implement the gtm in Next js. There are two easy steps to this.

Installing react-gtm-module package

First, you will have to include the react-gtm-module in the package.json file. To do that, open a command prompt and navigate to your app root folder, and type

npm install react-gtm-module --save

or

edit your package.json file and add "react-gtm-module": "^2.0.11" as a dependency.

Inserting the tracking code

Now pick a shared page (as mentioned in the google page scripts option above) and insert the gtm tracking code. TagManager.initialize({ gtmId: 'GTM-XXXXX' }); For example, the below code illustrates the react gtm implementation in the _app.js file.

import { useEffect } from 'react';
import TagManager from 'react-gtm-module';

function MyApp({ Component, pageProps }) {
  useEffect(() => {
      TagManager.initialize({ gtmId: 'GTM-XXXXX' });
  }, []);
  return <Component {...pageProps}/>
}
export default MyApp

The problem: Google Analytics not tracking internal page navigations

So far, everything seems to be in place. When you enter your website by typing the URL, you will notice that google analytics tracks the visit. But once you start navigating within your website by clicking react or next <Link> elements, you will not see any subsequent clicks registered. In other words, Google is unable to track page navigations occur within our website. Therefore, Google can track only initial page loads where a full page load occurs.

The reason

The reason is React js or Next js does a full page load only when the page is loaded initially. They do not refresh the page in consequent navigations. That's the correct behavior. That's how we experience those seamless and efficient page transitions. Therefore, our google tracking scripts are executed only once, when we initially visit the page.

The solution

The easiest solution is to add a history change trigger in the Google tag manager console. We can tackle the code on our application side and implement a solution. But there is a built-in solution for this in the Google tag manager console. The History Change trigger can capture all the navigations perform on the client-side using React or Next router links.

  • Log into google tag manager.
  • Click Triggers
Google tag manager triggers
Figure 1 : Adding a trigger in Google tag manager
  • Click New -> Trigger Configuration and select History Change trigger.
History Change trigger
Figure 2 : Trigger Configuration Select History Change trigger
  • Make sure to click All History Changes.
  • Name the trigger and click save.
Saving History Change trigger
Figure 3 : Give a name and save the trigger

Don't forget to publish your workspace container.
That's all to it. Now start a debug session by clicking the Preview button on the top right. Once you click start, the tag manager will open a debug window connected to your website. You can use this window to navigate your website links.

Google tag manager debugger
Figure 4 : Srart a debug session by clicking the Preview button on the top right

You will notice that there is a History created for every page transition that happens within the website. Every page refresh will result in Container, DOM, and Window events.

Google tag manager history change
Figure 5 : Google tracks every transition by creating a history event

Conclusion

Nextjs does a full page load only when the page is loaded initially. It does not refresh the page in consequent navigations. Therefore, the Google Analytics tracking scripts are executed only at the initial page load. To overcome this, we can use Google's History Change trigger. The History Change trigger fires when the URL fragment changes or when the site uses the HTML 5 push state API.

Lance
By: Lance
Lance is a software engineer with over 15 years of experience in full-stack software development.
Read more...

Leave a comment

No Comments