🎉

Next.jsでGoogle Analyticsの設定

2023/03/18に公開

Google Analyticsの設定方法
通常は<head>タグ内にトラッキングコードを仕込めば完成ですが、Nextjsは少し違うのでメモ
アナリティクスのトラッキングコードの取得などは各自調べて取得してください。

設定方法

まずNextjsはtypescriptと普通のjavascriptがありますが、今回はtypescript版の話です。

typescriptに対応するために@types/gtag.jsのパッケージをインストールします。

$ npm install -D @types/gtag.js

lib/gtag.tsを作成
環境変数は画面側で使用する値なので、頭にNEXT_PUBLIC_をつけておきます。
これをつけることで、画面側で環境変数を使用することができます。

lib/gtag.ts
export const GA_ID = process.env.NEXT_PUBLIC_GA_ID || '';

続いてpages/_app.tsxに設定を記述します。
next/scriptScriptを使用しています。
ページがインタラクティブになった後実行されるようにstrategyにはafterInteractiveを設定しています。
他の設定は公式サイト参照
公式サイト

pages/_app.tsx
import '@/styles/globals.css'
import type { AppProps } from 'next/app'
import Layout from '@/components/Layout'
+ import Script from 'next/script'
+ import * as gtag from '@/lib/gtag'

export default function App({ Component, pageProps }: AppProps) {
  return (
    <>
+      <Script
+        strategy='afterInteractive'
+        src={`https://www.googletagmanager.com/gtag/js?id=${gtag.GA_TAG_ID}`}
+      />
+      <Script
+        id='gtag-init'
+        strategy='afterInteractive'
+        dangerouslySetInnerHTML={{
+          __html: `
+            window.dataLayer = window.dataLayer || [];
+            function gtag(){dataLayer.push(arguments);}
+            gtag('js', new Date());
+          
+            gtag('config', '${gtag.GA_TAG_ID}');
+          `,
+        }}
+      />
      <Layout>
        <Component {...pageProps} />
      </Layout>
    </>
  )
}

以上でタグの設定は完了
ただこれだとページ遷移に対応していないので、ページ遷移に対応する

ページ遷移対応

lib/gtag.tsにページ遷移対応の関数を作成
ページ遷移が発生したタイミングで実行することで、Google Analyticsにデータを送信する
(if (!GA_TAG_ID) returnとGA_IDの|| ''の記述がなくてエラーになってた。解決に時間かかった。。どっちか記述してたらエラーにならない。)

lib/gtag.ts
export const GA_ID = process.env.NEXT_PUBLIC_GA_ID || '';

+ export const pageview = (url: string) => {
+  if (!GA_TAG_ID) return;
+  window.gtag('config', GA_TAG_ID, {
+    page_path: url,
+  });
+}

pages/_app.tsxで先程作成したページ遷移の関数を呼び出す処理の追加
next/routeを使用して、ページ遷移が完了した時に発火するrouteChangeCompleteのイベントリスナーとしてpageviewを設定する。urlはイベントが発火した時に渡される

イベントリスナーへの登録・削除はuseEffectを使用しておこなう

pages/_app.tsx
import '@/styles/globals.css'
import type { AppProps } from 'next/app'
import Layout from '@/components/Layout'
import Script from 'next/script'
import * as gtag from '@/lib/gtag'
+ import { useEffect } from 'react'
+ import { useRouter } from 'next/router'

export default function App({ Component, pageProps }: AppProps) {
+  const router = useRouter()
+  useEffect(() => {
+    const handleRouteChange = (url: string) => {
+      gtag.pageview(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=${gtag.GA_TAG_ID}`}
      />
      <Script
        id='gtag-init'
        strategy='afterInteractive'
        dangerouslySetInnerHTML={{
          __html: `
            window.dataLayer = window.dataLayer || [];
            function gtag(){dataLayer.push(arguments);}
            gtag('js', new Date());
          
            gtag('config', '${gtag.GA_TAG_ID}');
          `,
        }}
      />
      <Layout>
        <Component {...pageProps} />
      </Layout>
    </>
  )
}

以上でページ遷移も対応したGoogle Analyticsの設定は完了です。

参考文献
https://ebisu.com/next-react-website/

Discussion