Next.js: 添加GA脚本代码?

创建于 2016-10-30  ·  74评论  ·  资料来源: vercel/next.js

嗨,您好!

我目前正在将我的网站转换为next.js项目,并且无法弄清楚如何在页面上添加Google Analytics(分析)脚本标记。 有什么想法吗?

干杯,
罗宾

最有用的评论

不需要react-ga 。 将Google跟踪代码管理器与<Head>组件一起使用以注入分析数据。 为了使它在nextjs / react中工作,必须对Google跟踪代码管理器代码进行一些小的更改:

<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>
    <noscript dangerouslySetInnerHTML={{__html: `<iframe src="https://www.googletagmanager.com/ns.html?id=GTM-XXXXXXX" height="0" width="0" style="display:none;visibility:hidden;"></iframe>`}} />

image

所有74条评论

结帐<Head>

@robinvdvleuten我建议您创建一个GoogleTagManager组件,并将其包含在Head中或

正如人们提到的,您可以使用Head标签或类似https://github.com/react-ga/react-ga的反应友好型解决方案

有关使react-ga与next.js配合使用的任何提示?

@gtramontina它应该工作。 否则,我是react-ga贡献者之一,因此我可以提供帮助

不需要react-ga 。 将Google跟踪代码管理器与<Head>组件一起使用以注入分析数据。 为了使它在nextjs / react中工作,必须对Google跟踪代码管理器代码进行一些小的更改:

<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>
    <noscript dangerouslySetInnerHTML={{__html: `<iframe src="https://www.googletagmanager.com/ns.html?id=GTM-XXXXXXX" height="0" width="0" style="display:none;visibility:hidden;"></iframe>`}} />

image

我建议一个更好的解决方案来跟踪客户端页面视图:自动跟踪。 有关更多信息,请参见https://github.com/MoOx/phenomic/issues/384

@不可言喻的举个例子是很棒的,因为经过一些谷歌搜索后我仍然感到困惑😃是否可以重新打开?

  • @MoOx似乎暗示没有必要react-ga,应改用Google AutoTrack
  • 但是自动跟踪会指示使用访问window对象的代码创建脚本标签,因此在服务器端无法正常工作
  • 无论如何,如果使用诸如react-ga之类的react组件,应将其放在哪里? 在rendercomponentWillMountgetInitialProps ? 这并不是很清楚,因为它假设您使用react-router并为所有页面一次加载代码。

页面跟踪在服务器渲染页面时以及导航到另一个页面时均应起作用。 很高兴看到整个事情如何在具有Head,页面布局HOC等的典型Next应用程序中进行集成。

如果您认为与Next.js + Google Analytics(分析)自动跟踪相比,是否有更好/更简单/更省力/更先进的组合,也将非常高兴...

我可以调查一下

2017年1月17日,星期二,7:59SébastienDubois通知单@ github.com
写道:

@impronunciable https://github.com/impronunciable很棒
有一个例子,经过一些谷歌搜索后我仍然感到困惑fused
重新开放?

  • @MoOx https://github.com/MoOx似乎暗示react-ga不是
    必要时,应使用Google AutoTrack
    改为https://github.com/googleanalytics/autotrack
  • 但是自动跟踪会指示创建一个脚本标签,其中包含以下代码
    访问窗口对象,因此在服务器端不起作用
  • 无论如何,如果使用诸如react-ga之类的React组件,应该在哪里
    它被放? 在渲染中? componentWillMount? getInitialProps? 不是
    超级清晰,因为它假设您使用react-router并加载
    为所有页面一次编码。

页面跟踪应该在服务器呈现页面时和
然后导航到另一个页面。 看到如何
整个过程应该集成到带有Head,page的典型Next应用程序中
布局HOC等

很高兴知道您是否认为有更好/更简单/更少
比Next.js + Google繁琐/更多的最新组合
Analytics自动跟踪...

-
您收到此邮件是因为有人提到您。
直接回复此电子邮件,在GitHub上查看
https://github.com/zeit/next.js/issues/160#issuecomment-273108099或静音
线程
https://github.com/notifications/unsubscribe-auth/AAKHp9-2bfLXj2hMGlNlkqUSRqEL7R2Cks5rTJ8kgaJpZM4KkXxa

可以肯定的是,仅在客户端注入自动跟踪就绰绰有余-无需考虑服务器端。

有关示例,请参见https://github.com/MoOx/react-toulouse/commit/c42045d1001ab813c5d7eae5ab2f4f8c08c0025e 。 它不使用下一个,但我想它应该很容易适应。

是的,我们不想跟踪服务器渲染,因为它将混淆位置等信息。

不,您不需要,因为它将由客户端处理:请记住,页面是由客户端请求的,并且将在客户端浏览器中呈现:)

好的,我没有意识到代码不应在服务器端运行。 所以我按照@MoOx的建议使用了自动跟踪,我认为这应该可以工作: https :

只是尚未确认它是否可以正确计算浏览量,这对我来说是新的

您可以使用“实时”视图轻松调试GA。

@MoOx是的,这就是困扰我的地方,当我在另一个选项卡中同时访问https://relate.now.sh时,我在实时面板中看不到任何东西(0个活动用户)

我仍然没有得到这个...我编写的代码没有任何数据。

我看到的所有示例似乎都需要<script href="https://www.google-analytics.com/analytics.js" async />但Head中的内容似乎未在客户端中执行? (我的console.log没有打印在浏览器控制台中...)

一个例子还是很值得赞赏appreciated

您是如何工作的? 我一直在尝试在componentDidMount上调用综合浏览量函数。

生产应用GA检查失败。

@luandro不记得详细信息,但是如果有帮助,您可以看一下我上面链接的提交

我做了并尝试了。 我的操作与您相同,在顶部调用configureAnalytics ,在componentWillMount上访问综合浏览量,但在GA Check上仍然无法得到结果。

在您的代码中,似乎您实际上并没有在任何地方连接page hoc ,是吗?

@luandro只需添加ga(‘set’, ‘page’, window.location.pathname); ga(‘send’, ‘pageview’);即可更改综合浏览量网址。

也许还有一种更“ next.js”的方式来执行此操作,但是在页面上运行WRT的脚本时,我发现如果我创建了Script组件,如下所示:

// modules/Script.js
export default ({children}) => (
  <script dangerouslySetInnerHTML={{__html: `(${children.toString()})();` }}></script>
);

然后,我可以这样做对我有用:

import Document, { Head, Main, NextScript } from 'next/document'
import Script from '../modules/Script';

export default class MyDocument extends Document {

  render () {
    return (
      <html>
        <body>
          <Main />
          <Script>
            {
              () => {
                console.log('foo');
              }
            }
          </Script>
          <NextScript />
        </body>
      </html>
    )
  }
}

需要注意的是,您必须将所有内容都包含在函数中。

是否可以跟踪各个网页浏览量而无需在每个页面上显式调用ga('send','pageview')。 如果我们绝对必须这样做,那么从确定ga是否已加载的角度来调用它呢?

是否可以通过某种方式绑定路由更改事件以记录网页浏览量?

@karthikiyengar我正在使用上面其他人建议的react-ga ,并在每页componentDidMount上记录综合浏览量。

import ReactGA from 'react-ga'

export const initGA = () => {
  console.log('GA init')
  ReactGA.initialize('UA-xxxxxxxx-x')
}
export const logPageView = () => {
  ReactGA.set({ page: window.location.pathname })
  ReactGA.pageview(window.location.pathname)
}
componentDidMount () {
    initGA()
    logPageView()
  }

@vinaypuppal是每个页面组件都使用initGA的惯例吗?

@rongierlach我正在使用Layout组件,该组件在ReactGA内的componentDidMount() ReactGA上调用initializepageview方法。

export default class extends Component {
  componentDidMount() {
    ReactGA.initialize('UA-1234567-1')
    ReactGA.pageview(document.location.pathname)
  }

  render() {
    return (
      <div>
        {this.props.children}
     </div>
    )
}

这是我完成过的最干净的方法,就好像页面是服务器渲染的一样,它需要初始化。 我敢肯定,如果有客户端渲染的话,有一个钩子可以绕过初始化。

@notrab您可能不会缺少浅层渲染吗? 它们将只是您的应用程序过渡,并且您的布局组件可能不会重新安装。 这就是我必须抓住的那些。

componentDidMount() {
    ReactGA.initialize('xx-xxxxxxx-x')
    let trackMe = true

    if (trackMe) {
      ReactGA.pageview(document.location.pathname)
      trackMe = false
    }

    Router.onRouteChangeStart = () => {
      NProgress.start()
      this.store.dispatch(transitionPage(true))
      trackMe = true
    }
    Router.onRouteChangeComplete = () => {
      NProgress.done()
      this.store.dispatch(transitionPage(false))
      if (trackMe) { ReactGA.pageview(document.location.pathname) }
    }
    Router.onRouteChangeError = () => {
      NProgress.done()
      this.store.dispatch(transitionPage(false))
    }

    this.store.dispatch(calculateResponsiveState(window))
  }

试图使其正常运行,但Google Analytics(分析)仍然没有回应。 这是我在react-ga.js

import ReactGA from 'react-ga'

const dev = process.env.NODE_ENV !== 'production'

export const initGA = () => {
  ReactGA.initialize("UA-XXXXXXXXX-X", {
    debug: dev,
  })
}

export const trackPageView = (
  pageName = window.location.pathname + window.location.search
) => {
  ReactGA.set({page: pageName})
  ReactGA.pageview(pageName)
}

export const trackCustomEvent = (category, action) =>
  ReactGA.event({category, action})

export default undefined

而我的索引页:

import {initGA, trackPageView} from '../modules/react-ga.js'
[...]
Index.componentDidMount = function() {
    initGA()
    trackPageView()
}

当然,用我的实际代码替换了UA代码。

@filostrato您如何解决的? 我也坚持下去。 :)

@exogenesys最终将其放入utils/analytics.js

import ReactGA from 'react-ga'

const dev = process.env.NODE_ENV !== 'production'

export const initGA = () => {
  ReactGA.initialize("UA-xxxxxxxxx-x", {
    debug: dev,
  })
}

export const logPageView = (
  pageName = window.location.pathname + window.location.search
) => {
  ReactGA.set({page: pageName})
  ReactGA.pageview(pageName)
}

export const trackCustomEvent = (category, action) =>
  ReactGA.event({category, action})

export default undefined

并更改了我的Layout.js以扩展React.Component

export default class Layout extends React.Component {
    componentDidMount () {
      if (!window.GA_INITIALIZED) {
        initGA()
        window.GA_INITIALIZED = true
    }
    logPageView()
  }

  render () {
    return (
      <Main>
        <Header />
        {this.props.children}
      </Main>
    )
  }
}

没有找到一种使它在使用getInitialProps的组件中工作的方法,但是由于Layout.js不能正常工作; 不知道如果我想要更详细的统计信息该怎么做,但是当我谈到它时,我将跨越那座桥梁。

@filostrato做到了。 非常感谢。 :)

大家好

我也刚刚在自己的网站上处理过GA的实现,这就是我想出的。

首先,我使用了@notrab的解决方案,它看起来很简单明了:

export default class extends Component {
  componentDidMount() {
    ReactGA.initialize('UA-XXXXXXX-X')
    ReactGA.pageview(document.location.pathname)
  }

  render() {
    …
  }
}

但是,我注意到:

  • 当我在不同类型的页面之间切换时,执行了componentDidMount ,因此多次调用了initialize函数。
  • 当我在不同类型的页面之间切换时,只执行了componentDidMount ,因此只有在调用pageview函数时,才=>我的网站上有video页面类型, GA Live视图,即在不同视频页面之间切换时,仅跟踪了初始视频页面

我创建了一个高阶组件来解决这两个问题。 对于第一个,我使用@filostrato的解决方案。

import React, { Component } from 'react';
import ReactGA from 'react-ga';
import Router from 'next/router';

const debug = process.env.NODE_ENV !== 'production';

export default (WrappedComponent) => (
  class GaWrapper extends Component {
    constructor (props) {
      super(props);
      this.trackPageview = this.trackPageview.bind(this);
    }

    componentDidMount() {
      this.initGa();
      this.trackPageview();
      Router.router.events.on('routeChangeComplete', this.trackPageview);
    }

    componentWillUnmount() {
      Router.router.events.off('routeChangeComplete', this.trackPageview);
    }

    trackPageview (path = document.location.pathname) {
      if (path !== this.lastTrackedPath) {
        ReactGA.pageview(path);
        this.lastTrackedPath = path;
      }
    }

    initGa () {
      if (!window.GA_INITIALIZED) {
        ReactGA.initialize('UA-XXXXXX-XX', { debug });
        window.GA_INITIALIZED = true;
      }
    }

    render() {
      return (
        <WrappedComponent {...this.props} />
      );
    }
  }
);

并在您的<Layout> / <PageWrapper> / <PageScaffold>组件或您所说的任何组件中:

import GaWrapper from './ga-wrapper';

const PageScaffold = () => (…);

export default GaWrapper(PageScaffold);

也许对任何人都有帮助。

我不喜欢Router.router.events.…的调用,因为这不是文档API的一部分。 但是,当我尝试调用Router.onRouteChangeComplete应该是正确的方法)时,出现了ReferenceError,因为onRouteChangeCompleteundefined 。 也许文档已经过时了?

这在next.js网站上为我工作。 解决了我在react-ga的常规实现中遇到的“窗口未定义”错误。

@osartun解决方案为我工作。 谢谢! 👍

感谢@osartun的代码,我能够提出以下解决方案, pageview使用Google的新gtag (代替_universal analytics_脚本)触发pageview事件:

pages/_document.js

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

const GA_TRACKING_ID = '..';

export default class MyDocument extends Document {
  render() {
    return (
      <html lang="en-AU">
        <Head>
          <script async src={`https://www.googletagmanager.com/gtag/js?id=${GA_TRACKING_ID}`} />
          <script
            dangerouslySetInnerHTML={{
              __html: `
                window.dataLayer = window.dataLayer || [];
                function gtag(){dataLayer.push(arguments)};
                gtag('js', new Date());
                gtag('config', '${GA_TRACKING_ID}');
              `,
            }}
          />
        </Head>
        ...
      </html>
    );
  }
}

scaffold.js / layout.js / wraper.js /无论您的项目名称是什么:

import url from 'url';
import Router from 'next/router';

const GA_TRACKING_ID = '...';

const withPageViews = WrappedComponent =>
  class GaWrapper extends React.Component {
    componentDidMount() {
      // We want to do this code _once_ after the component has successfully
      // mounted in the browser only, so we use a special semiphore here.
      if (window.__NEXT_ROUTER_PAGEVIEW_REGISTERED__) {
        return;
      }

      window.__NEXT_ROUTER_PAGEVIEW_REGISTERED__ = true;
      let lastTrackedUrl = '';

      // NOTE: No corresponding `off` as we want this event listener to exist
      // for the entire lifecycle of the page
      // NOTE: This does _not_ fire on first page load. This is what we want
      // since GA already tracks a page view when the tag is first loaded.
      Router.router.events.on('routeChangeComplete', (newUrl = document.location) => {
        if (newUrl === lastTrackedUrl || !window.gtag) {
          return;
        }

        // Don't double track the same URL
        lastTrackedUrl = newUrl;

        // Believe it or not, this triggers a new pageview event!
        // https://developers.google.com/analytics/devguides/collection/gtagjs/single-page-applications
        window.gtag('config', GA_TRACKING_ID, {
          page_path: url.parse(newUrl).path,
        });
      });
    }

    render() {
      return <WrappedComponent {...this.props} />;
    }
  };

const PageScaffold = () => (…);

export default withPageViews(PageScaffold);

对于任何迟到的人, @kylewiedman的解决方案不起作用的原因是因为Router事件是在componentDidMount内部定义的。 在组件外部定义它们似乎可以解决问题:

https://gist.github.com/trezy/e26cb7feb2349f585d2daf449411d0a4

使用gtag@trezy似乎不需要import ReactGA from 'react-ga'

我使用了您的<script dangerouslySetInnerHtml={...} />示例,并将这一行添加到注入中:

window.gaTrackingId = '${gaTrackingId}';

之后,此轻量级技巧开始起作用:

Router.onRouteChangeComplete = () => {
  if (window.gtag) {
    window.gtag('config', window.gaTrackingId, {
      page_location: window.location.href,
      page_path: window.location.pathname,
      page_title: window.document.title,
    });
  }
};

不再提取相当大的analytics.js ,但仍会跟踪所有页面!

由于这并不明显,因此在存储库中有一个示例会很好。

或下一个Google Analytics(分析)资料库🕵️

@prichodko非常感谢您整理此示例!

此处提供官方示例: https

发现相当不错的库,并添加到componentDidMount()的主布局文件中,并且似乎可以正常工作。 有据可查,没有喧嚣

https://www.npmjs.com/package/react-gtm-module

@andylacko确实,我已经将它修复了一些问题,例如HTTPS: https :

仅在此处添加我的解决方案,以防以后对某人有用。

我使用了react-ga,但是相同的逻辑应该与其他ga工具一起使用。

每当用户单击新路线时,都会在客户端触发_app.js的getInitialProps。 (第一次它将在服务器端运行)。

componentDidMount_app.js仅在客户端运行。

因此,在我的_app.js ,添加了以下几行代码


static async getInitialProps({ Component, router, ctx }) {
    let pageProps = {}

    if (Component.getInitialProps) {
      pageProps = await Component.getInitialProps(ctx);      
    }

    // client-side only, run on page changes, do not run on server (SSR)
    if (typeof(window) === "object") {
      ReactGA.pageview(ctx.asPath);
    }
    return { pageProps, router }
  }


  componentDidMount() {
    // client-side only, run once on mount
    ReactGA.initialize('UA-XXXXXXX-3');
    ReactGA.pageview(window.location.pathname + window.location.search);
  }

当页面在服务器中呈现时, getInitialProps不会发生任何变化,因为我将GA代码包装在typeof(window) === "object"

在客户端, getInitialProps不会第一次运行,因为所有内容都是由服务器呈现的。 GA在客户端的componentDidMount内部设置。

随后的路由更改(即使是同一路由)也会在客户端触发getInitialProps ,并触发ga事件。

仅在此处添加我的解决方案,以防以后对某人有用。

我使用了react-ga,但是相同的逻辑应该与其他ga工具一起使用。

每当用户单击新路线时,都会在客户端触发_app.js的getInitialProps。 (第一次它将在服务器端运行)。

componentDidMount_app.js仅在客户端运行。

因此,在我的_app.js ,添加了以下几行代码


static async getInitialProps({ Component, router, ctx }) {
    let pageProps = {}

    if (Component.getInitialProps) {
      pageProps = await Component.getInitialProps(ctx);      
    }

    // client-side only, run on page changes, do not run on server (SSR)
    if (typeof(window) === "object") {
      ReactGA.pageview(ctx.asPath);
    }
    return { pageProps, router }
  }


  componentDidMount() {
    // client-side only, run once on mount
    ReactGA.initialize('UA-XXXXXXX-3');
    ReactGA.pageview(window.location.pathname + window.location.search);
  }

当页面在服务器中呈现时, getInitialProps不会发生任何变化,因为我将GA代码包装在typeof(window) === "object"

在客户端, getInitialProps不会第一次运行,因为所有内容都是由服务器呈现的。 GA在客户端的componentDidMount内部设置。

随后的路由更改(即使是同一路由)也会在客户端触发getInitialProps ,并触发ga事件。

嗨,威尔。 在Webpack中包含ReactGA(因为它在客户端运行)是否会对构建大小产生重大影响?

@ChrisEdson https://github.com/react-ga/react-ga整个库压缩了161kb。

嗯说实话,那绝对是巨大的!

在2019年2月28日星期四19:01,William Li [email protected]写道:

@ChrisEdson https://github.com/ChrisEdson
https://github.com/react-ga/react-ga整个库压缩了161kb。

-
您收到此邮件是因为有人提到您。
直接回复此电子邮件,在GitHub上查看
https://github.com/zeit/next.js/issues/160#issuecomment-468395136或静音
线程
https://github.com/notifications/unsubscribe-auth/AC5okwth_o_BLLPeqIcSBmhKineAhYfgks5vSCeUgaJpZM4KkXxa

这是整个库在GitHub上列出的数字。
打包到应用中后,如何查看实际尺寸?

从我的iPhone发送

于2019年3月1日15:43,克里斯·埃德森[email protected]写道:

嗯说实话,那绝对是巨大的!

在2019年2月28日星期四19:01,William Li [email protected]写道:

@ChrisEdson https://github.com/ChrisEdson
https://github.com/react-ga/react-ga整个库压缩了161kb。

-
您收到此邮件是因为有人提到您。
直接回复此电子邮件,在GitHub上查看
https://github.com/zeit/next.js/issues/160#issuecomment-468395136或静音
线程
https://github.com/notifications/unsubscribe-auth/AC5okwth_o_BLLPeqIcSBmhKineAhYfgks5vSCeUgaJpZM4KkXxa

-
您收到此邮件是因为您发表了评论。
直接回复此电子邮件,在GitHub上查看,或使该线程静音。

因此,最小的脚本为15kb。 很小

我将捆绑分析我的webpack,并报告其在实践中增加了多少。

在大约500kb的总包大小中,我的ReactGA增加了大约27kb。 在宏伟的计划中,这真是太小了。

仅在此处添加我的解决方案,以防以后对某人有用。

我使用了react-ga,但是相同的逻辑应该与其他ga工具一起使用。

每当用户单击新路线时,都会在客户端触发_app.js的getInitialProps。 (第一次它将在服务器端运行)。

componentDidMount_app.js仅在客户端运行。

因此,在我的_app.js ,添加了以下几行代码


static async getInitialProps({ Component, router, ctx }) {
    let pageProps = {}

    if (Component.getInitialProps) {
      pageProps = await Component.getInitialProps(ctx);      
    }

    // client-side only, run on page changes, do not run on server (SSR)
    if (typeof(window) === "object") {
      ReactGA.pageview(ctx.asPath);
    }
    return { pageProps, router }
  }


  componentDidMount() {
    // client-side only, run once on mount
    ReactGA.initialize('UA-XXXXXXX-3');
    ReactGA.pageview(window.location.pathname + window.location.search);
  }

当页面在服务器中呈现时, getInitialProps不会发生任何变化,因为我将GA代码包装在typeof(window) === "object"

在客户端, getInitialProps不会第一次运行,因为所有内容都是由服务器呈现的。 GA在客户端的componentDidMount内部设置。

随后的路由更改(即使是同一路由)也会在客户端触发getInitialProps ,并触发ga事件。

如果您使用的是NextJS 9,则会出现一个问题,即禁用自动预渲染。 想知道是否有更好的放置ReactGA.pageview(ctx.asPath); ,将其从getInitialProps中删除意味着我们可以删除getInitialProps而不是按照此处概述的那样强制退出自动预渲染: https ://err.sh/next.js/opt-out-automatic-prerendering。

更新:我找到了with-google-analytics示例(https://github.com/zeit/next.js/tree/canary/examples/with-google-analytics)并借用了以下内容: Router.events.on('routeChangeComplete', url => ReactGA.pageview(url))我需要对此进行测试,以确保url正确,但看起来像正确的方式。 我删除了getInitialProps方法,并将其添加到类声明上方。

@GodOfGrandeur听起来不错,将尝试使用。 没有使上述版本正常工作或看起来像这样https://medium.com/@austintoddj/using -google-analytics-with-next-js-423ea2d16a98在_app.js中添加代码似乎会触发所需的任何地方而且我也喜欢它没有在服务器上触发(虽然没有问题)。

不需要任何第三方,如果您使用的是gtag,请使用我创建的以下代码

<script
    async
    src="https://www.googletagmanager.com/gtag/js?id=%your code here%" >
</script>
<script dangerouslySetInnerHTML={
    { __html: `
        window.dataLayer = window.dataLayer || [];
        function gtag(){window.dataLayer.push(arguments)}
        gtag("js", new Date());
        gtag("config", "<%your code here%>");
    `}
}>
</script>

另一种选择是使用useEffect() 。 我已经在Layout.js文件中完成了此操作。

useEffect(() => {
  if (process.env.NODE_ENV === 'production') {
    window.dataLayer = window.dataLayer || []
    function gtag() {
      dataLayer.push(arguments)
    }
    gtag('js', new Date())
    gtag('config', '{GOOGLE ANALYTICS CODE}', {
      page_location: window.location.href,
      page_path: window.location.pathname,
      page_title: window.document.title,
    })
  }
})

<Head>

<Head>
  <script async src="https://www.googletagmanager.com/gtag/js?id={GOOGLE ANALYTICS CODE}"></script>
</Head>

@reinink只是想提一下,您可能希望将一个空数组作为第二个useEffect以便它在初始渲染后仅运行一次函数。

useEffect(() => {...}, [])

扩展@reinink的解决方案,这是我用来包装布局组件/模板的有效HOC。

import React, { useEffect } from 'react'
import Head from 'next/head'
const GoogleAnalyticsHOC = ({ children }) => {
  useEffect(() => {
    if (process.env.NODE_ENV === 'production') {
      window.dataLayer = window.dataLayer || []
      // eslint-disable-next-line
      function gtag() {
        window.dataLayer.push(arguments)
      }
      gtag('js', new Date())
      gtag('config', process.env.GOOGLE_ANALYTICS_ID, {
        page_location: window.location.href,
        page_path: window.location.pathname,
        page_title: window.document.title
      })
    }
  }, [])
  return (
    <>
      <Head>
        <script async src={`https://www.googletagmanager.com/gtag/js?id=${process.env.GOOGLE_ANALYTICS_ID}`} />
      </Head>
      {children}
    </>
  )
}
export default GoogleAnalyticsHOC

它没有经过广泛的测试,但是可以正常工作,并且使我成为本地运行的实时访问者。 :)

我找到了本指南-这是推荐的方法(使用react-ga)吗?

我想建议的方法是使用以下官方示例:

https://github.com/zeit/next.js/tree/canary/examples/with-google-analytics

它已经发布在这里。 有时我希望github问题更像是stackoverflow,在问题之后立即接受并突出显示一些答案(当消息和表情符号过多时,这是不够的。一种选择是限制对此文章的评论,因此人们会创建一个新问题在创建过程中,他们会发现已经创建了类似的问题(由于具有“类似问题”功能),并且有答案(但是,表情符号的答案在悠久的历史中间消失了,所以在github上找到答案不是很方便)。

它已经发布在这里。 有时候我希望github问题更像是stackoverflow,在问题之后紧紧地接受并突出显示一些答案(当消息和表情符号过多时....

Github正在此仓库的“讨论”选项卡上对此进行原型制作。

Screenshot 2020-04-08 at 16 59 58

@janbaykara哇,真的吗? 我们都以相同的方式思考:)我希望他们能找到一种将问题翻译成讨论的方法,或者是同一回事(如果将功能合并到问题中,并且所有现有的讨论都将成为问题)。 但是感谢您的答复!

@ 3lonious我个人放弃了Google Analytics(分析),因为它通常不能很好地适用于SPA。 (确实很糟糕的经验,尤其是对于SSR + CSR和难以跟踪的双重事件)

关于Next.js,请查看https://github.com/UnlyEd/next-right-now/blob/v2-mst-aptd-gcms-lcz-sty/src/components/pageLayouts/Head.tsx (使用next/Head ),这就是我在应用程序中添加脚本标签的方式。

不要犹豫,看看NRN https://unlyed.github.io/next-right-now ,这意味着它是Next.js“如何做X”的一个很好的例子,应该为您省去很多麻烦。

我不确定我是否知道它,我在该文件中看不到任何脚本标签?

这也是可行的解决方案。 我尚未对其进行广泛的测试,因此请自己进行测试。

pages/_document.js ,将此添加到您的<Head> 。 请参阅有关如何覆盖文档文件的文档

<script async src='https://www.googletagmanager.com/gtag/js?id=YOUR_GA_TRACKING_ID'></script>
<script
    dangerouslySetInnerHTML={{
        __html: `
            window.dataLayer = window.dataLayer || [];
            function gtag(){dataLayer.push(arguments)}
            gtag('js', new Date());

            gtag('config', 'YOUR_GA_TRACKING_ID');
              `
      }}>
</script>

它将流量至少报告给我的Google Analytics(分析)帐户。

@ 3lonious脚本标签和样式标签的工作方式相同。
根据经验,上述解决方案也适用。 (这就是我过去让GA工作的方式)

好的,谢谢大家。 我会尽力找你

好吧,我想我已经做好了

谢谢安东。 好吧,我有一个新的给你

我有一个用于客户服务的聊天应用程序,但是该脚本标签不起作用吗? 有任何想法吗?

它告诉我在体内添加第二个标签? 你怎么办?
Screen Shot 2020-06-19 at 6 48 22 AM

TBT怎么样? 如果您添加Google Analytics(分析),则会降低速度得分

TBT怎么样? 如果您添加Google Analytics(分析),则会降低速度得分

这是因为他们建议将脚本放在内容之前。 如果将其放在内容下,则分数不会降低。

我个人看不到将脚本放在第一位的真正好处。 如果页面加载因某种原因被破坏了,而HTML并未完全加载而被中止了,那么我可能不会将其视为命中之类的。

我正在与nextjs合作。 我正在尝试使用react google place自动完成API。 并想插入API的那些脚本标签? 我应该在哪里插入这些脚本标记?

_app.js

```js
从“ react-ga”导入ReactGA;

componentDidMount() {
  ReactGA.initialize("XX-XXXXXXXXX-X", { debug: false });
  ReactGA.set({ page: this.props.router.pathname });
  ReactGA.pageview(this.props.router.pathname);
  this.unlisten = this.props.router.events.on("routeChangeComplete", (router) => {
      ReactGA.set({ page: router });
      ReactGA.pageview(router);
    });
}

这真可笑。 不,实际上这很可悲。 等不及React,接下来,整个生态系统就会消失。

此页面是否有帮助?
0 / 5 - 0 等级