🪂

Next.jsのサイトにGoogle Analyticsを導入する

2021/06/25に公開
3

1. Googla Analytics

(1) アカウント作成

(2)プロパティ作成

(3)ビジネスの概要

(4)choose a platform

(5)ウェブサイトを定義

2. Editor作業

(1)Google AnalyticsのIDを.envに記述する

Analytics IDの場所

管理/データストリーム/ウェブ ストリームの詳細/測定 ID

.env.production等に下記貼り付け

.env.ptoduction
NEXT_PUBLIC_GOOGLE_ANALYTICS_ID=UA-SOME_ANALYTICS_ID-1

UA-SOME_ANALYTICS_ID-1 = 先ほどのAnalytics ID

(2)GAイベントを発火させる関数を作成する

・src/hooks/usePageView.ts
・src/lib/gtag.ts
・src/types/googleAnalytics/event.ts
作成

usePageView.ts

src/hooks/usePageView.ts
import { useEffect } from 'react'
import { useRouter } from 'next/router'

import * as gtag from '../lib/gtag'

export default function usePageView() {
  const router = useRouter()
  console.log(gtag.GA_ID)
  useEffect(() => {
    if (!gtag.existsGaId) {
      return
    }

    const handleRouteChange = (path, { shallow }) => {
      if (!shallow) {
        gtag.pageview(path)
      }
    }

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

gtag.ts

src/lib/gtag.ts
export const GA_ID = process.env.NEXT_PUBLIC_GOOGLE_ANALYTICS_ID ?? ''

// IDが取得できない場合を想定する
export const existsGaId = GA_ID !== ''

// PVを測定する
export const pageview = (path) => {
  window.gtag('config', GA_ID, {
    page_path: path,
  })
}

// GAイベントを発火させる
export const event = ({ action, category, label, value = '' }) => {
  if (!existsGaId) {
    return
  }

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

event.ts

src/types/googleAnalytics/event.ts
type ContactEvent = {
  action: 'submit_form'
  category: 'contact'
  label: string
}

type ClickEvent = {
  action: 'click'
  category: 'other'
  label: string
}

export type Event = ContactEvent | ClickEvent

_document.tsxにGAのスクリプトを書き込む

_document.tsx
import Document, { Head, Main, NextScript } from 'next/document'
import { existsGaId, GA_ID } from '../src/lib/gtag'

export default class MyDocument extends Document {
  render() {
    return (
      <html lang="ja">
        <Head>
          {/* Google Analytics */}
          {existsGaId && (
            <>
              <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>
        <body>
          <Main />
          <NextScript />
        </body>
      </html>
    )
  }
}

_app.tsxにPVをカウントするイベントを記述する

app.tsx
import { AppProps } from 'next/app'
import '../styles/globals.scss'
import HeadCompo from '../components/domains/HeadCompo'
import React from 'react'
+ import usePageView from '../src/hooks/usePageView'

const App = ({ Component, pageProps }: AppProps) => {
+ usePageView()
  return (
    <>
      <HeadCompo />
      <Component {...pageProps} />
    </>
  )
}

export default App

GAイベントをReactコンポーネントに設定する

import React, { useState } from 'react'
import Link from 'next/link'
+ import * as gtag from '../../../src/lib/gtag'

const Profile: React.FC<Props> = () => {
  const ClickEvent = () => {
    gtag.event({
      action: 'click_event',
      category: 'link_button',
      label: 'event',
    })
  }

  return (
    <div>
	  <Link href="https://www.facebook.com/example">
	    <a target="_blank" 
+	    onClick={ClickEvent}>
	      <IconButton/>
	    </a>
	  </Link>
    </div>
  )
}

export default Profile

TypeScript対応をする

next-env.d.ts
interface Window {
  // pageviewのため
  gtag(type: 'config', googleAnalyticsId: string, { page_path: string })
  // eventのため
  gtag(
    type: 'event',
    eventAction: string,
    fieldObject: {
      event_label: string
      event_category: string
      value?: string
    },
  )
}

Analytics Debug Viewで確認する

(1)localhost立上げ

yarn dev

(2)Debug Viewの拡張機能を追加 ONに

https://chrome.google.com/webstore/detail/google-analytics-debugger/jnkmfdileelhofjcijamephohjechhna/support?hl=ja

このように出れば成功

こちらを参考にさせていただきました。
https://panda-program.com/posts/nextjs-google-analytics

Discussion

プログラミングをするパンダプログラミングをするパンダ

こんばんは。私の技術記事「Next.jsでGoogle Analyticsを使えるようにする」の内容と同じコードが散見されたのでコメントしました。

https://panda-program.com/posts/nextjs-google-analytics

内容を転載するのは構わないのですが、その場合は引用元として私の記事のURLを記事内に追加お願いします。

あるいは、この記事の内容自体他でも転載されているため、もし自分以外の他の方の記事を参考にした場合は、そちらの記事URLを記載お願いしたいと思います。

もしこの行為を問題だと認識していない場合は、「Qiitaで記事を公開するときに気を付けるべきマナーについて 〜無断でネットや書籍の内容を丸写しするのはやめよう〜」 をご覧ください。


該当のコード

usePageView.ts

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

import * as gtag from '../lib/gtag'

export default function usePageView() {
const router = useRouter()
console.log(gtag.GA_ID)
useEffect(() => {
if (!gtag.existsGaId) {
return
}

const handleRouteChange = (path, { shallow }) => {
  if (!shallow) {
    gtag.pageview(path)
  }
}

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

}, [router.events])
}

gtag.ts

export const GA_ID = process.env.NEXT_PUBLIC_GOOGLE_ANALYTICS_ID ?? ''

// IDが取得できない場合を想定する
export const existsGaId = GA_ID !== ''

// PVを測定する
export const pageview = (path) => {
window.gtag('config', GA_ID, {
page_path: path,
})
}

// GAイベントを発火させる
export const event = ({ action, category, label, value = '' }) => {
if (!existsGaId) {
return
}

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

event.ts

type ContactEvent = {
action: 'submit_form'
category: 'contact'
label: string
}

type ClickEvent = {
action: 'click'
category: 'other'
label: string
}

export type Event = ContactEvent | ClickEvent

Ren ShimosawaRen Shimosawa

こんばんは。
確かにこちらのページも参考の1つにさせていただきました。
引用元の記載漏れ、申し訳ありません。
引用元に記載いたしました。
ご指摘いただきありがとうございました。