Open14

Next.js&GoogleAnalytics設定

ピン留めされたアイテム
kcabokcabo

結論 2パターン

解決したい課題は、SPAのページ遷移をどうアナリティクスに伝えるか
Next.js、GA4を想定

①GA4の拡張計測機能におまかせ (私はこちらを採用)

_document.js
        <Head>
          {GA_TRACKING_ID && (
            <>
              <script
                async
                src={`https://www.googletagmanager.com/gtag/js?id=${GA_TRACKING_ID}`}
              />
              <script
                dangerouslySetInnerHTML={{
                  __html: `
                    window.dataLayer = window.dataLayer || [];
                    function gtag(){dataLayer.push(arguments);}
                    gtag('js', new Date());
                    gtag('config', '${GA_TRACKING_ID}');
                  `,
                }}
              />
            </>
          )}
        </Head>

GA_TRACKING_IDの部分は環境変数から取得してください。ブラウザからも見えるようにNEXT_PUBLIC_を冒頭につけます。

.env
NEXT_PUBLIC_GA_ID=G-XXXXXXXX
const GA_TRACKING_ID = process.env.NEXT_PUBLIC_GA_ID || '';

そして、必ず「ブラウザの履歴イベントに基づくページの変更」機能を有効にする
「管理」>「プロパティ」>「データストリーム」>「ウェブサイト」>「拡張計測機能」>「詳細設定を表示」から設定可能(デフォルトでON)

②Hooksを使用し、マニュアルで送信する(プロダクションではこちらが無難かも?)

公式で案内されているやり方。①で使用する機能を使わない場合はこちらを選択する。
①はGA4前提でしたが、こちらはUAでも使えそうです。
上記の_document.jsに加えて_app.jsgtag.jsを編集

_app.js
import { useEffect } from 'react'
import { useRouter } from 'next/router'
import { pageview } from '../lib/gtag'

const App = ({ Component, pageProps }) => {
  const router = useRouter()
  useEffect(() => {
    router.events.on('routeChangeComplete', pageview)
    return () => {
      router.events.off('routeChangeComplete', pageview)
    }
  }, [router.events])

  return <Component {...pageProps} />
}

export default App
gtag.js
export const GA_TRACKING_ID = process.env.NEXT_PUBLIC_GA_ID || '';

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

加えて、必ず上記の「ブラウザの履歴イベントに基づくページの変更」機能を無効にすること!
GA4のデフォルトでは有効になっており、そのままにするとページ閲覧イベントが二重で送信されてしまう

(Appコンポーネントはアンマウントされるのか?クリーンアップコードを書く必要はあるのか?)

waddy_uwaddy_u

ちょうど調べていたので助かりました。ありがとうございます。GA4、おまかせだと拡張計測機能も勝手にやってくれそうなので便利ですね。

UAなのかGA4なのか明示されていない情報が多い

これには同意せざるを得ません。GA4いい感じなのでもっと情報できてきてほしいですねー

kcabokcabo

まだスクラップなのに見つけてくださりありがとうございます!笑 参考になれば幸いです
アプリ側で計測のことをあまり考えたくないので、たしかにGA側でよしなにやってほしいかな~ってところです。
気づきにくい割に重要な話なのでNextjsかGoogleからか公式にアナウンスしてほしいところですよね~

kcabokcabo

Next.jsで作成したアプリにGoogleAnalyticsを導入する

GAにはUAとGA4の二種類がある
新バージョンのGA4を前提にする
←どちらなのか明示されてない資料が多すぎる

https://github.com/vercel/next.js/tree/canary/examples/with-google-analytics
まず公式

これに従うと

  • TypeScript対応ができない
  • ページビューが二重で記録される

という不具合が起きた

今回のサイトはJAMStackなSSG。

TypeScript対応はnpm install -D @types/gtag.jsで瞬殺

二重の方は先にこんな記事があった。
https://zenn.dev/okumura_daiki/articles/839685a90c06db
ちなみに当方では全てのページで二重記録される

kcabokcabo

解決策

https://stackoverflow.com/questions/65460306/getting-redundant-pageview-events-with-ga4-and-nextjs
こちらが参考になる。

Basically GA4 introduces something called "Enhanced measurement" which tracks more stuff than GA used to. This setting is on by default and annoyingly overrides gtag('config', { send_page_view: false }). I'm not sure if this should be submitted to Google as a bug or we should simply stop trying to handle history changes manually and let GA do its magic.

This behavior can be disabled by going to Admin in GA, then to your property, choosing Data Streams, then choosing the stream that your app is using and disabling "Enhanced measurement" altogether:

Or by disabling tracking browser history in particular (click on the cog icon showing up when "Enhanced measurement" is on to see this):


ここの「ブラウザの履歴イベントに基づく~」をオフ
忘れずに保存する

kcabokcabo

GA側でよしなに全部やってくれる??

「ブラウザの履歴イベントに基づくページの変更」とある。Nextでの挙動はSPAだが、ブラウザーのヒストリースタックにページをプッシュする挙動のはずである。だからブラウザの戻るボタンが機能する
ということは変な設定をせずともGA側が上手く解釈してくれるのでは??

つまり最初に二重でカウントされてしまったのは

  • _app.tsxにHookとして書いたマニュアルの発火
  • 「ブラウザの履歴イベントに基づくページの変更」による発火
    が同時に起きていたから?(実際、後者をオフにしたら正常になった)
    ということは後者をオンにして前者をオフにしたら同様に解決できるかも???

→無理でした

というのも、たしかに二重にはならないし発火もするのだけれど、全てがランディングページ(gtag.jsを読み込んだページ)のビューになる。
/top/article/1/article/2/about/top という遷移も、/topが5回見られた扱いになる
例えば/article/2のタイミングでブラウザのページリロードを挟むと以降の閲覧は全て/article/2扱いになる。

→ でもなくてpage_pathpage_locationで違う
page_locationではちゃんと計測できている

ちなみに両方消すとページをリロードしたタイミングでしか計測されなくなる

https://support.google.com/analytics/answer/9322688?hl=ja&ref_topic=9756175

gtag('config', '${GA_TRACKING_ID}', {
                      page_path: window.location.pathname,
                    });

コレやってるのにpage_path効いてない

kcabokcabo

GAのデバッグをしたいよ~

https://chrome.google.com/webstore/detail/google-analytics-debugger/jnkmfdileelhofjcijamephohjechhna
こんなのがあるけれど最終更新日は2019年9月3日。GA4はその後に登場したのでは?
https://support.google.com/analytics/answer/7201382?hl=ja
公式ではGA4でも使えるみたいに言うてるけど。。

みつけたああ

https://tagassistant.google.com/
別ウィンドウで開きつつ確認できる
拡張でGA無効にしてるけど見られる
https://support.google.com/tagassistant/answer/10039345#zippy=%2Cin-this-article

多分localhostにも接続できちゃう

kcabokcabo

つまり

  • 拡張計測機能を完全に使わない(あるいはブラウザの履歴イベントに基づくページの変更をオフにした場合。おそらくUAの場合はそもそもこの機能がない)とき、公式のやりかたに従い、Hooksを使って手動でpageviewイベントを発火させる

Next.jsのissuesでの議論ではGA4とUAの違い、GA4における拡張計測機能についての言及をしているものが少なかった。拡張計測機能がない前提だと確かにhooksを使わないと行けない

↑これでもいいんだけど、個人的にはSPAでの遷移を検知できるGAの機能を活用したい。こちらが書くコードを減らしたい。
→Hooksを使わない方法をさぐりたい

https://github.com/vercel/next.js/issues/24637
結構Hooks周りが大変そうにしてる

kcabokcabo

疑問

  • なぜタグを_document.tsxに書くのか?_app.tsxじゃだめなのか?
  • next/script使えないか?
  • page_pathpage_locationが異なるのはなぜか?
    • gtag('config', 'G-ED3FW8BLJL', {page_path: window.location.pathname,});が読み込まれるのは初読み込み時=ランディング時だけだからか?
kcabokcabo

Vercelのアナリティクス使うとかいう選択肢もある

kcabokcabo

To ensure accurate reporting, we recommend disabling this feature at this time. If you have opted to enable automatic pageview (and other events) tracking in your GA4 property, you are going to want to disable that feature prior to pushing your changes live to avoid potentially double-counting pageviews or accidentally overriding what is going to be sent from the data layer.
Visit the Admin > Property > Data Streams section to turn off the Enhanced measurement feature:
https://www.bounteous.com/insights/2021/04/06/tracking-single-page-applications-google-analytics-4

非推奨の人もいる…
https://medium.com/@tagticians/what-to-consider-before-enabling-google-analytics-app-webs-enhanced-measurements-66352ca9d497

たしかに挙動を見るに少し不安定? scrollイベントとか勝手にキャプチャされているし

https://www.optimizesmart.com/single-page-apps-in-google-analytics-4/
かなり詳しいがここでも「ヒストリの自動発火じゃなくて手動発火のほうがいいよ」みたいになってる

kcabokcabo

ZennにGA登録しているけどどの設定にしたらいいのだろう...?

kcabokcabo

公式リポジトリ色々読み漁ったけどこれが限界(疑問山積み)
とりあえずは要件満たせてるしいいか
にしてももっと困っている人いてもいいだろ。。。

ちゃんと記事にしよう