Add Google Analytics through GTM (Google Tag Manager) on Next.js
Tags: gtm, googletagmanager, nextjs, googleanalytics
Published: 2020-07-28 08:01:34

Last week we released a brand new website (https://uwork.no) for our amazing client (uWork AS) and had to get Google Tag Manager (GTM) up and running, easy, we thought! Well, not quite!

For those interested, the stack is:
- Next.js
- TailwindCSS
- Laravel (API)
- Kubernetes (K8S) hosted on DigitalOcean
- Bitbucket with Bitbucket Pipelines for deployment


# The problem
Since we had GTM already setup, we thought all we needed to do is to inject the GTM script. And so we did!

We checked if the script was loaded ✅, we also checked if GTM was loaded correctly using Google Tag Manager extension for Chrome ✅, yep everything looked OKEY!

Then after completed the checklist before release we pushed to PROD and run DEPLOY 🚀😎

Next day we where monitoring Google Analytics and found out that all the data where from the index page (path: `/`), so we started to investigate and found out:
- **Moving from page to page did not fire our GA tag!**

# The solution
After using the whole day researching and reading on internet and found different suggestions on how to solve this, below we will show you our implementation using the classic Google Analytics tag.

Inject GMT script in `pages/_document.tsx`:
```tsx
<>
    {/* Google Tag Manager */}
    <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_ID}');`,
        }}
    />
    {/* End Google Tag Manager */}
    {/* Google Tag Manager (noscript) */}
    <noscript
        dangerouslySetInnerHTML={{
            __html: `<iframe src="https://www.googletagmanager.com/ns.html?id=${GTM_ID}" height="0" width="0" style="display:none;visibility:hidden"></iframe>`,
        }}
    />
    {/* End Google Tag Manager (noscript) */}
</>
```

Remember to replace / define `GTM_ID`!

Then create an page view util function, `utils/gtm.ts`:
```ts
export const GTMPageView = (url: string) => {
    interface PageEventProps {
        event: string;
        page: string;
    }

    const pageEvent: PageEventProps = {
        event: 'pageview',
        page: url,
    };
    //@ts-ignore
    window && window.dataLayer && window.dataLayer.push(pageEvent);
    return pageEvent;
};
```

After that we need to run "pageview" event on every page, this can be done by setting up an listener (routeChangeComplete) on our Router using useEffect, `pages/_app.tsx`:
```tsx
import { AppProps } from 'next/app';
import Router from 'next/router';
import React, {useEffect } from 'react';
import { GTMPageView } from '../utils/gtm';

function MyApp({ Component, pageProps }: AppProps) {
    // ...

    // Initiate GTM
    useEffect(() => {
        const handleRouteChange = (url: string) => GTMPageView(url);
        Router.events.on('routeChangeComplete', handleRouteChange);
        return () => {
            Router.events.off('routeChangeComplete', handleRouteChange);
        };
    }, []);

    // ...
}

export default MyApp;
```

Almost done, now we need to add a new Custom Event to fire our GA tag.

In GTM console:
1. Go to Triggers and click "New"
2. Name it as desired, in our case I'm naming it "PageViewCustom"
3. Under "Trigger configuration" select "Custom event", and under "Event name" write "pageview" <- this should the same as defined in your code/function `GTMPageView`.
![alt text][createCustomEvent]
4. Then go to Tags find you GA tag and configure to use the event we just created above.
![alt text][gtmGATag]
5. Test the changes and publish it :)

### UPDATE: Another alternative
You can as well use "History Change" trigger to achieve the same result.

That's all! Happy tracking 🙃

[createCustomEvent]: https://ornio.fra1.digitaloceanspaces.com/static/dev.to/20200728-ga-gta-nextjs/gtm-create-custom-event.png "Create Custom Event in Google Tag Manager"

[gtmGATag]: https://ornio.fra1.digitaloceanspaces.com/static/dev.to/20200728-ga-gta-nextjs/gtm-ga-all-pages-tag.png "Google Analytics tag in GTM"