如何加载带有next/script组件的谷歌标签管理器(Next.js 11)?

von4xj4u  于 2023-02-08  发布在  其他
关注(0)|答案(3)|浏览(184)

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组件?

u4vypkhs

u4vypkhs1#

必须将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"]
}

Information about next.js eslint configuration.

yfwxisqw

yfwxisqw2#

我的最终解决方案是拆分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;
l7mqbcuq

l7mqbcuq3#

内联脚本需要一个“id”参数,以便Next可以进行内部检查并避免再次加载脚本。
文档中提到了这一点,但他们在第一个版本中遗漏了这一点。
它后来被添加为修补程序,因此升级您的Next将解决此问题
修补程序-https://github.com/vercel/next.js/pull/28779/files/11cdc1d28e76c78a140d9abd2e2fb10fc2030b82
讨论主题-https://github.com/vercel/next.js/pull/28779

相关问题