TypeError: window.gtag is not a function

11,636

Solution 1

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

Solution 2

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

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

Solution 3

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

For example,

npm install @types/gtag.js --save-dev  
Share:
11,636

Related videos on Youtube

La pach'
Author by

La pach'

Updated on May 26, 2022

Comments

  • La pach'
    La pach' almost 2 years

    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 :)

    • cbr
      cbr almost 4 years
      You'll either want to make sure that the google tag manager's script is loaded before your app bundle, or initialize it yourself in trackerPageView when it's used for the first time. And add a try-catch inside trackerPageView because if a user uses an ad blocker, the script will be blocked and window.gtag will not be initialized.
    • La pach'
      La pach' almost 4 years
      I all ready add a try-catch where I call it that's why I do not crash but got the pretty error message... Ok but how can I check if the google tag manager is loaded before my app bundle ? (I can publish more code if it's can help)
    • cbr
      cbr almost 4 years
      Make sure the <script> is before your <script>. And if (window.gtag) { }
    • bcjohn
      bcjohn almost 4 years
      where did you execute window.gtag, and where did you define function gtag()? You can reference this article to set up the google analytics.
    • Rohan Büchner
      Rohan Büchner almost 4 years
      Nextjs + GTM... Thats the problem, they can work, but you'll need to ensure it doesnt fire during a server render... thus odds are your next app is using SSR... & window is not available on the server... try wrap your GTM code in a check for window. eg if (window) {}
    • La pach'
      La pach' almost 4 years
      I just updated the post
    • La pach'
      La pach' almost 4 years
      Ok but that's what I did no? what you think ?
    • Rohan Büchner
      Rohan Büchner almost 4 years
      window.gtag will still break during ssr because window is undefined.
    • La pach'
      La pach' almost 4 years
      Ok so how should I fix the window undefined problem ? have you some suggestions
  • bcjohn
    bcjohn almost 4 years
    You should add the script which link to the gtm.
  • CoronelV
    CoronelV about 3 years
    In accord with @james and @h13o, npm install @types/gtag.js should be included in this answer
  • Appy Mango
    Appy Mango over 2 years
    This was the necessary addition for Next Js applications