类型错误:window.gtag 不是函数

La *_*ch' 9 typescript google-tag-manager reactjs next.js

我对 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
Run Code Online (Sandbox Code Playgroud)

我没有看到任何关于这个问题的文档,所以我发了一篇文章来集中有关这个问题的信息。

我的配置是一个 webApp(nextjs、Reactjs、typeScript、redux),希望这会有所帮助。

_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>
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

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);
  }
}

Run Code Online (Sandbox Code Playgroud)

我找到了临时解决方案!

所以目前我的 gtag 实现让我可以通过 GTM 检测到触发器和触发器,我只需设置一个新触发器

历史修改

现在它在每次历史记录修改时都会触发分配有此触发器的事件。我对 gtag 不太满意,但这对我来说已经足够了(目前),我仍然对我所做的实现感到恼火。我想找到正确的实施方式来清理我的矿井。

问题显然来自 SSR,因为窗口变量变得未定义(在 NodeJs 中不存在),从而出现上述错误。仍在搜索解决方案来修复它...

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

谢谢大家,祝你有美好的一天:)

jam*_*mes 8

在使用之前您需要检查窗口是否存在window

例如:

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

此外,您不需要将 Google 跟踪代码管理器脚本包装在<Fragment>

最后,默认情况下似乎gtag不是全局可用的。您必须根据此文档自行设置:https://developers.google.com/analytics/devguides/collection/gtagjs


小智 7

遇到同样的问题,我使用了与其他建议略有不同的版本:

if (typeof window.gtag !== 'undefined')
Run Code Online (Sandbox Code Playgroud)

  • 这是 Next Js 应用程序的必要补充 (2认同)

h13*_*13o 6

就我而言,我忘记添加@types/gtag.js.

例如,

npm install @types/gtag.js --save-dev  
Run Code Online (Sandbox Code Playgroud)