如何使用 next/script 组件 (Next.js 11) 加载 Google 标签管理器?
How to load Google Tag Manager with next/script component (Next.js 11)?
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;
它工作正常,它加载 google 标签管理器,但问题是它在每个页面导航中注入相同的脚本,这会产生重复的标签。
如何使用新的 Script
组件?
我的最终解决方案是分解 GTM 脚本。
将初始 dataLayer
对象放在 _document
页面的 window 上。
// _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;
我认为您应该为 <Script>
组件设置一个 id
。
接下来可以检查它是否已经渲染过,你不会有这些重复。
这是与 Next 关联的 eslint 规则:
next/script components with inline content require an id attribute to be defined to track and optimize the script.
参见: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"]
}
您的内联脚本需要一个“id”参数,以便 Next 可以在内部检查并避免再次加载脚本。
文档中提到了它,但他们在第一个版本中忽略了它。
后来作为补丁添加,因此升级您的 Next 可以解决此问题
补丁 - https://github.com/vercel/next.js/pull/28779/files/11cdc1d28e76c78a140d9abd2e2fb10fc2030b82
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;
它工作正常,它加载 google 标签管理器,但问题是它在每个页面导航中注入相同的脚本,这会产生重复的标签。
如何使用新的 Script
组件?
我的最终解决方案是分解 GTM 脚本。
将初始 dataLayer
对象放在 _document
页面的 window 上。
// _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;
我认为您应该为 <Script>
组件设置一个 id
。
接下来可以检查它是否已经渲染过,你不会有这些重复。
这是与 Next 关联的 eslint 规则:
next/script components with inline content require an id attribute to be defined to track and optimize the script.
参见: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"]
}
您的内联脚本需要一个“id”参数,以便 Next 可以在内部检查并避免再次加载脚本。
文档中提到了它,但他们在第一个版本中忽略了它。
后来作为补丁添加,因此升级您的 Next 可以解决此问题
补丁 - https://github.com/vercel/next.js/pull/28779/files/11cdc1d28e76c78a140d9abd2e2fb10fc2030b82