如何使用 next/script 组件(Next.js 11)加载 Google 跟踪代码管理器?

问题描述 投票:0回答:4

Next.js v11 发布了一个新的

Script
组件,该组件具有不同的策略。

建议使用

afterInteractive
策略加载 Google TagManager。

我已经尝试过了

// _app.js

import Script from 'next/script';

class MyApp extends App {
  public render() {
    const { Component, pageProps } = this.props;

    return (
      <>
        <Script strategy="afterInteractive">
          {`(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-XXXXXXX');`}
        </Script>
        <Component {...pageProps} />
      </>
    );
  }
}

export default MyApp;

它工作正常,它加载谷歌标签管理器,但问题是它在每个页面导航上注入相同的脚本,这会产生重复的标签。

如何使用新的

Script
组件?

javascript next.js google-tag-manager
4个回答
18
投票

您必须为您的

id
组件设置
<Script>
,因为它具有内联内容(无
src
属性)。

接下来可以检查它是否已经渲染,这样就不会出现这些重复。

这是与 Next 相关的 eslint 规则:

具有内联内容的 next/script 组件需要定义 id 属性来跟踪和优化脚本。

参见:https://nextjs.org/docs/messages/inline-script-id

所以你的解决方案可能是:

    <Script id="gtm-script" strategy="afterInteractive">{`...`}</Script>

您可能还应该为您的下一个项目安装 eslint :
运行

next lint
或安装 eslint 下一个配置:

yarn add -D eslint eslint-config-next

并至少使用以下内容定义文件 .eslintrc.json :

{
  "extends": ["next/core-web-vitals"]
}

有关 next.js eslint 配置的信息。


9
投票

我的最终解决方案是分解 GTM 脚本。

将初始

dataLayer
对象放置在
_document
页面的窗口上。

// _document.js

import Document, { Head, Html, Main, NextScript } from 'next/document';

export default class MyDocument extends Document {
  render() {
    return (
      <Html lang="en">
        <Head>
          <meta charSet="utf-8" />

          <script
            dangerouslySetInnerHTML={{
              __html:
                `(function(w,l){` +
                `w[l] = w[l] || [];w[l].push({'gtm.start':new Date().getTime(),event:'gtm.js'});` +
                `})(window,'dataLayer');`,
            }}
          />
        </Head>
        <body>
          <Main />
          <NextScript />
        </body>
      </Html>
    );
  }
}

使用

Script
组件加载GMT脚本(
_document
页面不允许使用)

// _app.js

import Script from 'next/script';

class MyApp extends App {
  public render() {
    const { Component, pageProps } = this.props;

    return (
      <>
        <Script src={`https://www.googletagmanager.com/gtm.js?id=GMT-XXXXXXX`} />
        <Component {...pageProps} />
      </>
    );
  }
}

export default MyApp;

2
投票

您的内联脚本需要一个“id”参数,以便 Next 可以在内部检查并避免再次加载脚本。

文档提到了这一点,但他们在第一个版本中错过了这一点。

后来作为补丁添加,因此升级您的 Next 可以解决此问题

补丁 - https://github.com/vercel/next.js/pull/28779/files/11cdc1d28e76c78a140d9abd2e2fb10fc2030b82

讨论主题 - https://github.com/vercel/next.js/pull/28779


0
投票

对于较新的 NextJS 版本(13 - 14),有一种更简单的方法(@next/第三方库):

  1. 运行
    npm install @next/third-parties@latest next@latest
    yarn add @next/third-parties@latest next@latest
  2. 在您的
    pages/_app.jsx
    /
    .tsx
    app/layout.tsx
    /
    .jsx
    中,添加

import { GoogleTagManager } from '@next/third-parties/google'

  1. <GoogleTagManager gtmId={process.env.NEXT_PUBLIC_GTM_ID} />
    添加到您的报税表中(在
    _app
    /
    layout
    文件中)
  2. NEXT_PUBLIC_GTM_ID
    添加到您的环境中或将
    {process.env.NEXT_PUBLIC_GTM_ID}
    替换为您的实际 GTM id
© www.soinside.com 2019 - 2024. All rights reserved.