如何在 next.js 应用程序中使用谷歌分析?

SHA*_*OOZ 46 javascript google-analytics reactjs styled-components next.js

我在 next.js 中使用 styled-components,所以我的样式需要在服务器端呈现,因此我如何将谷歌分析添加到我的网站?

我检查了next.js 谷歌分析示例,但正如我所说,由于使用了样式组件,我的 _document 文件有所不同。

// _document.js

import React from 'react'
import Document from 'next/document'
import { ServerStyleSheet } from 'styled-components'

class MyDocument extends Document {
  static async getInitialProps(ctx) {
    const sheet = new ServerStyleSheet()
    const originalRenderPage = ctx.renderPage

    try {
      ctx.renderPage = () => originalRenderPage({
        enhanceApp: (App) => (props) => sheet.collectStyles(<App {...props} />),
      })

      const initialProps = await Document.getInitialProps(ctx)
      return {
        ...initialProps,
        styles: (
          <>
            {initialProps.styles}
            {sheet.getStyleElement()}
          </>
        ),
      }
    } finally {
      sheet.seal()
    }
  }
}

export default MyDocument

Run Code Online (Sandbox Code Playgroud)

thi*_*ign 105

接受的答案不起作用。相反,要正确初始化gtag,请_document.js在您定义的地方或任何地方执行以下操作Head

import { Head } from 'next/document';

export default class MyDocument extends Document {
  render() {
    return (
      // ...
      <Head>
        <script
          async
          src="https://www.googletagmanager.com/gtag/js?id=[Tracking ID]"
        />

        <script
          dangerouslySetInnerHTML={{
            __html: `
              window.dataLayer = window.dataLayer || [];
              function gtag(){dataLayer.push(arguments);}
              gtag('js', new Date());
              gtag('config', '[Tracking ID]', { page_path: window.location.pathname });
            `,
          }}
        />
      </Head>
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

以上将跟踪页面加载时的页面浏览量。要跟踪导航,请将以下内容添加到_app.js

import { useRouter } from 'next/router';

export default const App = () => {
  const router = useRouter();

  const handleRouteChange = (url) => {
    window.gtag('config', '[Tracking ID]', {
      page_path: url,
    });
  };

  useEffect(() => {
    router.events.on('routeChangeComplete', handleRouteChange);
    return () => {
      router.events.off('routeChangeComplete', handleRouteChange);
    };
  }, [router.events]);

  return (
    // ...
  );
};
Run Code Online (Sandbox Code Playgroud)

也可以看看:

  • 最新版本的 GA 似乎不再需要“handleRouteChange”和“useEffect”。事实上,如果您手动侦听路由器事件,您将获得预期的 page_view 事件的**双倍**。较新的跟踪 ID 以“GA-”开头。 (7认同)
  • 我刚刚对此进行了测试。浏览量不会在导航更改时注册。这是因为 nextjs 不会在导航更改时刷新页面,它只是更改一些 props 并让 React 相应地重新渲染。 (6认同)
  • 这是否会在所有导航更改上注册新的页面访问? (2认同)
  • 不过,nextjs 路由器不会在导航更改时重新加载页面。 (2认同)

Jer*_*yal 35

使用 Typescript 使用 NextJS 设置 Google 分析

我正在为我的个人网站 ( https://github.com/GorvGoyl/Personal-Site-Gourav.io )使用以下设置,它运行良好,没有任何 linting 错误。仅对生产启用分析。

  • 创建一个Google 分析项目并获取测量 ID。
  • 在您的 NextJS 项目中,创建/lib/gtag.ts文件并添加您的 Google 测量 ID:
export const GA_TRACKING_ID = "<INSERT_TAG_ID>";

// https://developers.google.com/analytics/devguides/collection/gtagjs/pages
export const pageview = (url: URL): void => {
  window.gtag("config", GA_TRACKING_ID, {
    page_path: url,
  });
};

type GTagEvent = {
  action: string;
  category: string;
  label: string;
  value: number;
};

// https://developers.google.com/analytics/devguides/collection/gtagjs/events
export const event = ({ action, category, label, value }: GTagEvent): void => {
  window.gtag("event", action, {
    event_category: category,
    event_label: label,
    value,
  });
};
Run Code Online (Sandbox Code Playgroud)
  • 还要安装 gtag types
npm i -D @types/gtag.js
Run Code Online (Sandbox Code Playgroud)
  • 创建/pages/_document.tsx
import Document, { Html, Head, Main, NextScript } from "next/document";

import { GA_TRACKING_ID } from "../lib/gtag";

const isProduction = process.env.NODE_ENV === "production";

export default class MyDocument extends Document {
  render(): JSX.Element {
    return (
      <Html>
        <Head>
          {/* enable analytics script only for production */}
          {isProduction && (
            <>
              <script
                async
                src={`https://www.googletagmanager.com/gtag/js?id=${GA_TRACKING_ID}`}
              />
              <script
                // eslint-disable-next-line react/no-danger
                dangerouslySetInnerHTML={{
                  __html: `
            window.dataLayer = window.dataLayer || [];
            function gtag(){dataLayer.push(arguments);}
            gtag('js', new Date());
            gtag('config', '${GA_TRACKING_ID}', {
              page_path: window.location.pathname,
            });
          `,
                }}
              />
            </>
          )}
        </Head>
        <body>
          <Main />
          <NextScript />
        </body>
      </Html>
    );
  }
}

Run Code Online (Sandbox Code Playgroud)
  • 创建/pages/_app.tsx
import { AppProps } from "next/app";
import { useRouter } from "next/router";
import { useEffect } from "react";
import * as gtag from "../lib/gtag";
const isProduction = process.env.NODE_ENV === "production";

const App = ({ Component, pageProps }: AppProps): JSX.Element => {
  const router = useRouter();

  useEffect(() => {
    const handleRouteChange = (url: URL) => {
      /* invoke analytics function only for production */
      if (isProduction) gtag.pageview(url);
    };
    router.events.on("routeChangeComplete", handleRouteChange);
    return () => {
      router.events.off("routeChangeComplete", handleRouteChange);
    };
  }, [router.events]);
  // eslint-disable-next-line react/jsx-props-no-spreading
  return <Component {...pageProps} />;
};

export default App;

Run Code Online (Sandbox Code Playgroud)


Jør*_*gen 31

在您的_document.js重写getInitialProps方法中。您还可以覆盖该render方法。只需添加

  render() {
    return (
      <Html lang={this.props.lang || "en"}>
        <Head>
          <script
            dangerouslySetInnerHTML={{
              __html: `[google analytics tracking code here]`
            }}
          />
        </Head>
        <body>
          <Main />
          <NextScript />
        </body>
      </Html>
    );
  }
Run Code Online (Sandbox Code Playgroud)

确保导入所需的组件:

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


Ben*_*Yee 30

不要在这里使用最上面的答案禁止使用本机<script>标签,它应该在<head>标签之外定义。

这是在 NextJS 中包含脚本标签并配置 Google Analytics 的正确方法:

import Script from 'next/script'
import Head from 'next/head'

export default function Index() {
  return (
    <>
      <Head>
        <title>Next.js</title>
      </Head>
      <Script
        src="https://www.googletagmanager.com/gtag/js?id=GA_MEASUREMENT_ID"
        strategy="afterInteractive"
      />
      <Script id="google-analytics" strategy="afterInteractive">
        {`
          window.dataLayer = window.dataLayer || [];
          function gtag(){window.dataLayer.push(arguments);}
          gtag('js', new Date());

          gtag('config', 'GA_MEASUREMENT_ID');
        `}
      </Script>
    </>
  )
}
Run Code Online (Sandbox Code Playgroud)

欲了解更多信息:https://nextjs.org/docs/messages/next-script-for-ga

  • 这是正确的做法,谢谢。 (4认同)

ozg*_*zer 12

这是next.js推荐的方法。

/components/GoogleAnalytics.jsx

import Script from 'next/script'
import { useEffect } from 'react'
import { useRouter } from 'next/router'

const GA_TRACKING_ID = '...'

export default () => {
  const router = useRouter()
  useEffect(() => {
    const handleRouteChange = url => {
      window.gtag('config', GA_TRACKING_ID, { page_path: url })
    }
    router.events.on('routeChangeComplete', handleRouteChange)
    return () => {
      router.events.off('routeChangeComplete', handleRouteChange)
    }
  }, [router.events])

  return (
    <>
      <Script
        strategy='afterInteractive'
        src={`https://www.googletagmanager.com/gtag/js?id=${GA_TRACKING_ID}`}
      />
      <Script
        id='gtag-init'
        strategy='afterInteractive'
        dangerouslySetInnerHTML={{
          __html: `
            window.dataLayer = window.dataLayer || [];
            function gtag(){dataLayer.push(arguments);}
            gtag('js', new Date());
            gtag('config', '${GA_TRACKING_ID}', {
              page_path: window.location.pathname,
            });
          `
        }}
      />
    </>
  )
}

Run Code Online (Sandbox Code Playgroud)

/pages/_app.jsx

import GoogleAnalytics from './../components/GoogleAnalytics'

export default function App ({ Component, pageProps }) {
  return (
    <>
      <Component {...pageProps} />

      {
        process.env.NODE_ENV === 'production' &&
          <GoogleAnalytics />
      }
    </>
  )
}
Run Code Online (Sandbox Code Playgroud)

  • 这导致页面浏览量翻倍 (3认同)

小智 6

另一种对我来说效果很好的方法,无需dangerouslySetInnerHTML

  • 在public文件夹中新建一个js文件,内容为dangerouslySetInnerHTML.
  • 将创建的js文件添加到该_document.js文件中。

我返回的样本_document.js

<Html>
  <Head>
    <script async src="https://www.googletagmanager.com/gtag/js?id=UA-xxx-x"></script>
    <script src="/ga.js" async></script>
    {/*other scripts*/}
  </Head>
  <body>
    <Main />
      <NextScript />
  </body>
</Html>
Run Code Online (Sandbox Code Playgroud)