TypeError: window.gtag is not a function

Viewed 14568

I'm totally puzzled with GTM, I implemented it to my webSite to trigger some events to handle traffic, ect... It's be like 2 days I saw the following error :

Error from the trackerPageView =>  TypeError: window.gtag is not a function
    at _app.js:1
    at _app.js:1
    at commons.c57c1be722ad069a7405.js:1
    at Array.map (<anonymous>)
    at Object.emit (commons.c57c1be722ad069a7405.js:1)
    at commons.c57c1be722ad069a7405.js:1

I didn't see any doc about this problem so I make a post to centralize information about this problem.

My config is a webApp (nextjs, Reactjs, typeScript, redux), hopefully this will help.

_document.tsx :

import Document, { Head, Main, NextScript } from "next/document";
import { GA_TRACKING_ID } from "../lib/gtag";
import { Fragment } from "react";

export default class MyDocument extends Document {
  setGoogleTags() {
    return {
      __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','${GA_TRACKING_ID}');
          `,
    };
  }

  render() {
    return (
      <html lang="fr">
        <Head>
          <Fragment>
            <script dangerouslySetInnerHTML={this.setGoogleTags()} />
          </Fragment>
          <meta charSet="utf-8" />
          <meta name="viewport" content="width=device-width, initial-scale=1" />
          <meta name="theme-color" content="#000000" />
          <link
            rel="shortcut icon"
            href="***"
            crossOrigin="anonymous"
          />
          <link
            rel="stylesheet"
            href="***.css"
            crossOrigin="anonymous"
          />
        </Head>
        <body>
          <noscript>
            <iframe
              src={`https://www.googletagmanager.com/ns.html?id=${GA_TRACKING_ID}`}
              height="0"
              width="0"
              style={{ display: "none", visibility: "hidden" }}
            ></iframe>
          </noscript>
          <Main />
          <NextScript />
          <script
            type="text/javascript"
            id="hs-script-loader"
            async
            defer
            src="//js.hs-scripts.com/*****.js"
          ></script>
        </body>
      </html>
    );
  }
}

gtg/index.ts:

export const GA_TRACKING_ID = 'GTM-XXXX'

export default function trackPageView(url) {
    try {
      if (window.gtag)
        window.gtag("config", GA_TRACKING_ID, {
        page_location: url,
      });
  } catch (error) {
    console.log("Error from the trackerPageView => ", error);
  }
}

Solution I found temporary!

So currently my implementation of gtag let me to have firer and trigger detected by GTM, I just set a new trigger to

History modification

and now it's firing my events assigned with this trigger at each history modification. I'm not very confortable with gtag but this enough for me (for now), I'm still annoyed because of the implementation I did. I would like to find the right implementation to clean mine.

The problem clearly come from the SSR because the window variable is become undefined (don't exist in nodeJs) to the error above appear. Still search solution to fix it...

https://github.com/vercel/next.js/discussions/14980

Thx everyone and have a good day :)

5 Answers

You'll want to check for the existence of the window before using window.

For example:

if (typeof window !== 'undefined') {
  window.gtag("config", GA_TRACKING_ID, {
    page_location: url,
  });
}

Also you do not need to wrap your Google Tag Manager script in <Fragment>

Lastly, it looks like gtag is not something globally available by default. You have to set it up yourself according to this document: https://developers.google.com/analytics/devguides/collection/gtagjs

Had the same issue, i used a slightly different version than the other suggestions:

if (typeof window.gtag !== 'undefined')

In my case, I forgot to add @types/gtag.js.

For example,

npm install @types/gtag.js --save-dev  

It seems you don't define the gtag in _document.tsx, try to add the script in <Head>. Also, add the script which link to gtm.

<Head>
  <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>

In my case the problem was I used import Script from "next/script"; instead simple html script. Hope it 'll help to someone.

Related