如何通过 Google 标签管理器为 Next-Js 设置 Google 分析?

How to set up Google Analytics through Google Tag Manager for Next-Js?

以前我使用 react-ga npm 模块在我的下一个 js 应用程序中插入 google 分析。就是这样:

import ReactGA from 'react-ga'

export const initGA = () => {
  ReactGA.initialize('UA-*******-*', {
    titleCase: false
  })
}

export const logPageView = () => {
  if (window.location.href.split('?')[1]) {
    ReactGA.set({page: window.location.pathname + '?' + window.location.href.split('?')[1]})
    ReactGA.pageview(window.location.pathname + '?' + window.location.href.split('?')[1])
  } else {
    ReactGA.set({page: window.location.pathname})
    ReactGA.pageview(window.location.pathname)
  }
}

然后我在我的页眉中调用 logPageView 函数(已插入到我的应用程序的每个页面),如下所示:

  componentDidMount () {
    if (!window.GA_INITIALIZED) {
      initGA()
      window.GA_INITIALIZED = true
    }
    logPageView()
  }
  componentWillReceiveProps () {
    if (!window.GA_INITIALIZED) {
      initGA()
      window.GA_INITIALIZED = true
    }
    logPageView()
  }

现在我想使用 Google 跟踪代码管理器来处理 Analytics 页面视图。我该怎么做?

为了使用 Google 标签管理器,您应该在每个页面上注入您的标签管理器脚本。由于 _document.js 是每个页面的包装器,您应该将 GTM 脚本添加到标题部分的 _document.js,如下所示:

<Head>
  <script dangerouslySetInnerHTML={{
    __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','GTM-*****');`,
  }}>
  </script>
  ...
</Head>

现在您已准备好在 next-js 应用中使用 Google 跟踪代码管理器。您应该只继续处理 GTM 仪表板中的网页浏览量和其他与分析相关的内容。

要为单页应用程序(如 nextjs)设置 google 分析综合浏览量,您可以按照 these 步骤进行操作。

由于您使用的是 nextJS,因此无需从 Google Analytics 添加纯 javascript,您只需要 GA 跟踪 ID。

然后创建 util 函数:

export const event = ({ action, category, label, value }) => {
  window.gtag('event', action, {
    event_category: category,
    event_label: label,
    value: value
  })
}

并将此添加到您的 _document.js:

<script
  dangerouslySetInnerHTML={{
  __html: `
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());
  gtag('config', '${GA_TRACKING_ID}');
`}}
/>

之后,你只需要在页面/组件中导入util函数并调用:

gtag.event({
  action: 'submit_form',
  category: 'Contact',
  label: this.state.message
})

参考:example of NextJS with GA

我找到了更好的实现方式。我们可以为它使用 react-gtm-module 库。

正如 Ryan Elainska 在他们的博客中提到的,Google Tag Manager in Next.js 在我的 NextJS 安装的 _app.js 文件中:

import App, { Container } from 'next/app'
import React from 'react'
import './app.css'
import TagManager from 'react-gtm'

const tagManagerArgs = {
  id: 'GTM-XXXXXXX'
}

class MyApp extends App {
  componentDidMount () {
    TagManager.initialize(tagManagerArgs)
  }

  render () {
    const { Component, pageProps } = this.props
    return (
      <Container>
        <Component {...pageProps} />
      </Container>
    )
  }
}

export default MyApp

我在我的 next.js 应用程序中使用 redux

如果你使用 redux,这是一个很好的解决方案:redux-beacon + react-gtm-module.

这里是初始化代码。此代码可以在 _app.js 中使用钩子或 componentDidMount 触发,如果您使用的是 redux,则可以使用 redux 操作触发。

const dataLayer = { ...your dataLayer config... }
const tagManagerArgs = {
  gtmId: process.env.GTM_ID,
  auth: process.env.GTM_AUTH,
  preview: process.env.GTM_PREVIEW,
  dataLayer
}
TagManager.initialize(tagManagerArgs)

下面是用eventMap创建的中间件。

import { EventsMapper, createMiddleware } from 'redux-beacon'
import GoogleTagManager from '@redux-beacon/google-tag-manager'

const gtm = GoogleTagManager()

export const eventsMap: EventsMapper = action => {
  switch (action.type) {
    default:
      return []
  }
}


export const gtmMiddleware = createMiddleware(eventsMap, gtm)

我在 componentDidMount

中的 _app.js 中使用 react-gtm-module 和配置
 componentDidMount() {
    const tagManagerArgs = {
      gtmId = 'GTM-00001'
    }

    TagManager.initialize(tagManagerArgs);
  }

这是我在 2020 年 2 月 11 日更新的解决方案

不需要任何特殊的库,这里的一些答案看起来不完整。只需将脚本添加到 <Head> 并将脚本添加到 <body> in _document.js

import Head from 'next/document'  

<Head>
  <script dangerouslySetInnerHTML={{__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','GTM-XXXXXX');`}} />
</Head>
    
<body style={{ margin: 0 }}>
   <noscript dangerouslySetInnerHTML={{ __html: `<iframe src="https://www.googletagmanager.com/ns.html?id=GTM-XXXXXX"
        height="0" width="0" style="display:none;visibility:hidden"></iframe>`,
      }}
    />
    <Main />
    <NextScript />
</body>

旧 post,但我最近写了这篇文章,并在此处详细介绍了 2 个解决方案:https://morganfeeney.com/how-to/integrate-google-tag-manager-with-next-js

在 Next.js v11.0.0 之前,最简单的方法是使用自定义 _document。

在自定义 _document 中添加这样的 GTM 脚本:https://nextjs.org/docs/advanced-features/custom-document

import Head from 'next/document';
...

<Head>
  <script
    dangerouslySetInnerHTML={{
      __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','GTM-XXXX');`,
    }}
  />
</Head>

<body>
  <Main />
  <NextScript />
  <noscript
    dangerouslySetInnerHTML={{
      __html: `<iframe src="https://www.googletagmanager.com/ns.html?id=GTM-XXXX" height="0" width="0" style="display: none; visibility: hidden;" />`,
    }}
  />
</body>

但是您如何跟踪页面浏览量??

window.onLoad 在使用客户端路由进行导航时不会触发,因此即使您添加了脚本,它也没有按照您的预期执行。

我的首选方法是使用这样的函数:

export const gtmVirtualPageView = (rest) => {
  window.dataLayer?.push({
    event: 'VirtualPageView',
    ...rest,
  });
};

然后在_app.tsx中添加如下配置:

import '../styles/globals.css';
import { useEffect } from 'react';
import { useRouter } from 'next/router'
import { gtmVirtualPageView } from '../lib/gtm';

function MyApp({ Component, pageProps }) {
  const router = useRouter()

  useEffect(() => {
    const mainDataLayer = {
      pageTypeName: pageProps.page || null,
      url: router.pathname,
    };

    window.onload = () => window.dataLayer?.push({...mainDataLayer});

    gtmVirtualPageView(mainDataLayer);

  }, [pageProps])

  return <Component {...pageProps} />
}

export default MyApp

这允许通过 pageProps 将数据传递到数据层。