4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Next.jsでGoogle Analytics(gtag.js)のPageView送信

Last updated at Posted at 2020-01-07

Next.js を使ったサイトかつ、 import Link from 'next/link' で画面遷移をする際にGoogle AnalyticsのPageViewを送信するシンプルな方法を書いておきます。

react-ga, next-ga を使わずに Hocでシンプルに行うやり方。

実装方法

環境

  • next 9.1.7

Hocを作成

GA_MEASUREMENT_ID は書き換えてください。

このhocを next.js ではどのディレクトリに置けばいいかは
https://react-file-structure.surge.sh/
を参考にしてください。

import React, { Component } from 'react';
import Head from 'next/head';
import Router from 'next/router';

export default ComposedComponent => {
  return class withGA extends Component {
    static displayName = `withGA(${ComposedComponent.displayName})`;

    static async getInitialProps(ctx) {
      const pageProps = ComposedComponent.getInitialProps
        ? await ComposedComponent.getInitialProps(ctx)
        : {};

      return { ...pageProps };
    }

    componentDidMount() {
      Router.events.on('routeChangeComplete', () => {
        setTimeout(() => {
          window.gtag('config', 'GA_MEASUREMENT_ID', {
            page_title: window.document.title,
            page_location: window.location.href,
          });
        }, 0);
      });
    }

    render() {
      return (
        <>
          <Head>
            <script
              async
              src="https://www.googletagmanager.com/gtag/js?id= GA_MEASUREMENT_ID
            />
            <script
              dangerouslySetInnerHTML={{
                __html: `
                  window.dataLayer = window.dataLayer || [];
                  function gtag() { dataLayer.push(arguments); }
                  gtag('js', new Date());
                  gtag('config', 'GA_MEASUREMENT_ID');
                `,
              }}
            />
          </Head>
          <ComposedComponent {...this.props} />
        </>
      );
    }
  };
};

_app.js にラップ

pages/_app.js に↓にようにラップします

import React from 'react';
import App from 'next/app';

import withGA from 'your_path/withGA';

class CoreApp extends App {
  static async getInitialProps({ Component, ctx }) {
    let pageProps = {};
    if (Component.getInitialProps) {
      pageProps = await Component.getInitialProps(ctx);
    }
    return { pageProps };
  }

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

export default withGA(CoreApp);  // これをやりたいだけ

備考

componentDidMount で setTimeout入れているのは、 window.document.title がうまく取得できないためです。
いずれ改修されて不要になるかもしれません。
参考: https://github.com/zeit/next.js/issues/6025#issuecomment-467423149

下記のように console に出力しつつ、 A -> B -> C とページ遷移した際の C の送信で意味がわかります。

componentDidMount() {
  // titleが1つ前の画面のtitileになっている(CのときにBのtitle)
  console.log("1", {
    page_title: window.document.title,
    page_location: window.location.href,
  });

  Router.events.on('routeChangeComplete', () => {
    // titleが1つ前の画面のtitileになっている(CのときにBのtitle)
    console.log("2", {
      page_title: window.document.title,
      page_location: window.location.href,
    });

    setTimeout(() => {
      console.log("3", {
        page_title: window.document.title,
        page_location: window.location.href,
      });

      window.gtag('config', 'GA_MEASUREMENT_ID', {
        page_title: window.document.title,
        page_location: window.location.href,
      });
    }, 0);
  });
}

まとめ

「単純にPageViewを送信できればいいんだけどねー」という目的に対して
ググってもピンポイントでやりたいことの情報が見つからないのでまとめてみました。

4
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?