typescript TypeError:window.gtag不是函数

gmol1639  于 2023-01-21  发布在  TypeScript
关注(0)|答案(6)|浏览(249)

我完全困惑与GTM,我实现了它到我的网站触发一些事件来处理交通,等等...它就像2天,我看到以下错误:

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

我没有看到任何关于这个问题的文档,所以我发了一个帖子来集中关于这个问题的信息。
我的配置是一个webApp(nextjs,Reactjs,typeScript,redux),希望这会有所帮助。
_文件.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/索引.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);
  }
}

我找到了临时的解决方案!
因此,目前我的gtag实现允许GTM检测firer和trigger,我只是将一个新的trigger设置为
历史修改
现在它在每次修改历史记录时都会触发我的事件。我对gtag不是很满意,但这对我来说已经足够了(现在),我仍然因为我所做的实现而烦恼。我想找到正确的实现来清理我的。
这个问题很明显来自SSR,因为窗口变量变得未定义(不存在于nodeJ中),从而出现上述错误。仍在寻找解决方案来修复它...
https://github.com/vercel/next.js/discussions/14980
谢谢大家,祝你们有愉快的一天:)

2nc8po8w

2nc8po8w1#

在使用window之前,您需要检查窗口是否存在。
例如:

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

此外,您不需要将Google Tag Manager脚本 Package 在<Fragment>
最后,看起来gtag在默认情况下并不是全局可用的,你必须根据这个文档自己设置它:https://developers.google.com/analytics/devguides/collection/gtagjs

wlsrxk51

wlsrxk512#

有同样的问题,我用了一个稍微不同的版本比其他建议:

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

50few1ms3#

在我的例子中,我忘记添加@types/gtag.js
例如,

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

fkaflof64#

似乎您没有在_document.tsx中定义gtag,尝试在<Head>中添加脚本。另外,添加链接到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>
omjgkv6w

omjgkv6w5#

在我的例子中,问题是我使用了import Script from "next/script";而不是简单的html script。希望它能对某人有所帮助。

hec6srdp

hec6srdp6#

我已经实现了以下这篇文章,它的工作完美!https://www.learnbestcoding.com/post/22/reactjs-using-google-analytics-tag-manager

declare global {
  interface Window {
    dataLayer: Record<string, any>[];
  }
}

 React.useEffect(() => {
    const analytics = (
      w: Window,
      d: Document,
      s: string,
      l: string,
      i: string
    ) => {
      (w as any).dataLayer = (window as any).dataLayer || [];
      (w as any).dataLayer.push({
        "gtm.start": new Date().getTime(),
        event: "gtm.js",
      });
      var dl = l != "dataLayer" ? "&l=" + l : "";
      var scr = "https://www.googletagmanager.com/gtm.js?id=" + i + dl;
      /*
        To avoid Multiple installations of google tag manager detected warning
    */
      if (!scriptExists(scr)) {
        var f = d.getElementsByTagName(s)[0],
          j: HTMLScriptElement = d.createElement("script");
        j.async = true;
        j.src = scr;
        f?.parentNode?.insertBefore(j, f);
      }
    };
    const scriptExists = (url: string) => {
      var scripts = document.getElementsByTagName("script");
      for (var i = scripts.length; i--; ) {
        if (scripts[i].src == url) return true;
      }
      return false;
    };
    analytics(
      window,
      document,
      "script",
      "dataLayer",
      process.env.NODE_ENV !== "development" ? `${gaTrackingId}` : "GTM-XXXXXX"
    );
  }, [gaTrackingId]);

相关问题