🙆‍♀️

Nextjs AMPモードで Google Analyticsを動かしたい

2021/08/05に公開

最重要なこと

GA4ではなくユニバーサルアナリティクスのプロパティ(UA-始まりのID)を使うこと! (2021年8月4日現在、私調べ)

[AmpAnalytics <unknown id>] No triggers were found in the config. No analytics data will be sent.

GA4のIDでは動きませんでした...
https://github.com/ampproject/amphtml/issues/30903

実装方針

AMP対応ページはamp-analyticsを使って、それ以外は使わない

実装手順

環境変数使う

next.config.js
const config = {
  webpack5: false,
  webpack: (config) => {
  },
  ...
  env: {
    GOOGLE_ANALYTICS_ID: process.env.GOOGLE_ANALYTICS_ID,
  },
}

gtag.ts

yarn add @types/gtag.js
gtag.ts
declare global {
  interface Window {
    gtag: Gtag.Gtag
  }
}

export const GA_ID = process.env.GOOGLE_ANALYTICS_ID

export const existsGaId = GA_ID !== ''

export const pageview = (path) => {
  window.gtag('config', GA_ID, {
    page_path: path,
  })
}

export const event = ({ action, category, label, value = '' }) => {
  if (!existsGaId) {
    return
  }

  window.gtag('event', action, {
    event_category: category,
    event_label: JSON.stringify(label),
    value,
  })
}

_document.tsx

this.props.inAmpModeを使って、AMPページかどうかでスクリプトを分けています。

_document.tsx
...
import { existsGaId, GA_ID } from '@/utils/gtag'

class MyDocument extends Document {
  static async getInitialProps(ctx) {
...
    }
  }

  render() {
    const isAmp = this.props.inAmpMode
    const ampAnalyticsScriptObject = () => {
      return {
        vars: {
          account: GA_ID,
          gtag_id: GA_ID,
          config: {
            [GA_ID]: { groups: 'default' },
          },
        },
        triggers: {
          trackPageview: {
            on: 'visible',
            request: 'pageview',
          },
        },
      }
    }

    return (
      <Html>
        <script
          async
          custom-element="amp-analytics"
          src="https://cdn.ampproject.org/v0/amp-analytics-0.1.js"
        />
        {/* Google Analytics */}
        {existsGaId && !isAmp ? (
          <head>
            <script async src={`https://www.googletagmanager.com/gtag/js?id=${GA_ID}`} />
            <script
              dangerouslySetInnerHTML={{
                __html: `
                window.dataLayer = window.dataLayer || [];
                function gtag(){dataLayer.push(arguments);}
                gtag('js', new Date());
                gtag('config', '${GA_ID}', {
                  page_path: window.location.pathname,
                });`,
              }}
            />
          </head>
        ) : null}
        <Head />
        <body>
          {existsGaId && isAmp ? (
            <amp-analytics type="gtag" data-credentials="include">
              <script
                type="application/json"
                dangerouslySetInnerHTML={{
                  __html: JSON.stringify(ampAnalyticsScriptObject()),
                }}
              />
            </amp-analytics>
          ) : null}
          <Main />
          <NextScript />
        </body>
      </Html>
    )
  }
}

export default MyDocument

_app.tsx

useEffect使って、イベントを登録する

_app.tsx

// import '../styles/globals.css'
import { Layout } from '@/components/Layout'
import Router from 'next/router'
import React, { useEffect } from 'react'
import * as gtag from '@/utils/gtag'

function MyApp({ Component, pageProps }) {
  useEffect(() => {
    if (!gtag.existsGaId) {
      return
    }

    const handleRouteChange = (path) => {
      gtag.pageview(path)
    }

    Router.events.on('routeChangeComplete', handleRouteChange)
    return () => {
      Router.events.off('routeChangeComplete', handleRouteChange)
    }
  }, [])
  return (
    <Layout>
      <Component {...pageProps} />
    </Layout>
  )
}

export default MyApp


最重要なこと

GA4ではなくユニバーサルアナリティクスのプロパティを使うこと!

Discussion