Next.js&GoogleAnalytics設定
結論 2パターン
解決したい課題は、SPAのページ遷移をどうアナリティクスに伝えるか
Next.js、GA4を想定
①GA4の拡張計測機能におまかせ (私はこちらを採用)
<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_
を冒頭につけます。
NEXT_PUBLIC_GA_ID=G-XXXXXXXX
const GA_TRACKING_ID = process.env.NEXT_PUBLIC_GA_ID || '';
そして、必ず「ブラウザの履歴イベントに基づくページの変更」機能を有効にする
「管理」>「プロパティ」>「データストリーム」>「ウェブサイト」>「拡張計測機能」>「詳細設定を表示」から設定可能(デフォルトでON)
②Hooksを使用し、マニュアルで送信する(プロダクションではこちらが無難かも?)
公式で案内されているやり方。①で使用する機能を使わない場合はこちらを選択する。
①はGA4前提でしたが、こちらはUAでも使えそうです。
上記の_document.js
に加えて_app.js
とgtag.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
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コンポーネントはアンマウントされるのか?クリーンアップコードを書く必要はあるのか?)
Next.jsで作成したアプリにGoogleAnalyticsを導入する
GAにはUAとGA4の二種類がある
新バージョンのGA4を前提にする
←どちらなのか明示されてない資料が多すぎる
まず公式
これに従うと
- TypeScript対応ができない
- ページビューが二重で記録される
という不具合が起きた
今回のサイトはJAMStackなSSG。
TypeScript対応はnpm install -D @types/gtag.js
で瞬殺
二重の方は先にこんな記事があった。
ちなみに当方では全てのページで二重記録される解決策
こちらが参考になる。
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):
ここの「ブラウザの履歴イベントに基づく~」をオフ
忘れずに保存する
GA側でよしなに全部やってくれる??
「ブラウザの履歴イベントに基づくページの変更」とある。Nextでの挙動はSPAだが、ブラウザーのヒストリースタックにページをプッシュする挙動のはずである。だからブラウザの戻るボタンが機能する
ということは変な設定をせずともGA側が上手く解釈してくれるのでは??
つまり最初に二重でカウントされてしまったのは
-
_app.tsx
にHookとして書いたマニュアルの発火 - 「ブラウザの履歴イベントに基づくページの変更」による発火
が同時に起きていたから?(実際、後者をオフにしたら正常になった)
ということは後者をオンにして前者をオフにしたら同様に解決できるかも???
→無理でした
というのも、たしかに二重にはならないし発火もするのだけれど、全てがランディングページ(gtag.jsを読み込んだページ)のビューになる。
/top
→ /article/1
→ /article/2
→ /about
→ /top
という遷移も、/top
が5回見られた扱いになる
例えば/article/2
のタイミングでブラウザのページリロードを挟むと以降の閲覧は全て/article/2
扱いになる。
→ でもなくてpage_path
とpage_location
で違う
page_location
ではちゃんと計測できている
ちなみに両方消すとページをリロードしたタイミングでしか計測されなくなる
gtag('config', '${GA_TRACKING_ID}', {
page_path: window.location.pathname,
});
コレやってるのにpage_path
効いてない
GAのデバッグをしたいよ~
こんなのがあるけれど最終更新日は2019年9月3日。GA4はその後に登場したのでは? 公式ではGA4でも使えるみたいに言うてるけど。。
みつけたああ
拡張でGA無効にしてるけど見られる
多分localhostにも接続できちゃう
つまり
- 拡張計測機能を完全に使わない(あるいはブラウザの履歴イベントに基づくページの変更をオフにした場合。おそらくUAの場合はそもそもこの機能がない)とき、公式のやりかたに従い、Hooksを使って手動でpageviewイベントを発火させる
- このやり方だと色々あるけど公式リポのこちらのコードがめちゃシンプル
- メインブランチのこっちはあんまりメンテされてない...issuesで古くね?とか言われてる
- そんでもってこの書き方でいい気がする...
Next.jsのissuesでの議論ではGA4とUAの違い、GA4における拡張計測機能についての言及をしているものが少なかった。拡張計測機能がない前提だと確かにhooksを使わないと行けない
↑これでもいいんだけど、個人的にはSPAでの遷移を検知できるGAの機能を活用したい。こちらが書くコードを減らしたい。
→Hooksを使わない方法をさぐりたい
結構Hooks周りが大変そうにしてる
疑問
- なぜタグを
_document.tsx
に書くのか?_app.tsx
じゃだめなのか? -
next/script
使えないか?-
next/script
は_document.tsx
では使えない(クライアントサイドでうごく)-
next/script must not be placed in either a next/head component or in pages/_document.js. - https://nextjs.org/docs/basic-features/script
-
- こういう問題もあるみたいだからしばらく様子見?
-
-
page_path
とpage_location
が異なるのはなぜか?-
gtag('config', 'G-ED3FW8BLJL', {page_path: window.location.pathname,});
が読み込まれるのは初読み込み時=ランディング時だけだからか?
-
Vercelのアナリティクス使うとかいう選択肢もある
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
非推奨の人もいる…
たしかに挙動を見るに少し不安定? scrollイベントとか勝手にキャプチャされているし
かなり詳しいがここでも「ヒストリの自動発火じゃなくて手動発火のほうがいいよ」みたいになってる
react-ga
を使う記事などもありますが採用しませんでした。不要そうだったので
こちらに非推奨の理由がわかりやすく載ってます
ZennにGA登録しているけどどの設定にしたらいいのだろう...?
公式リポジトリ色々読み漁ったけどこれが限界(疑問山積み)
とりあえずは要件満たせてるしいいか
にしてももっと困っている人いてもいいだろ。。。
ちゃんと記事にしよう