Next.js に Google Tag Manager + Google Analytics 4 を導入するための整理
要件
- Next.js によるウェブアプリケーション
- すでにUAによる計測を行っている
- UAによる計測は、自動計測+特定のページだけconfigをオーバーライドしている(カスタムディメンジョン用)
- この状態で Google Analytics 4 による計測も同時に行いたい
- 既存のUAには影響がないようにしたい
- できればカスタムディメンジョンを付与したイベントも GA4で再現したい
検討項目
- Google Tag Manager を使うとアプリケーション側でイベントの制御を行うのではなく、GTMの管理コンソール側で制御できるようになる雰囲気があるのでまずGTM の導入を検討する
結論(やったこと)
- Google Tag manager と Google Analytics 4 を連携した
- Google Analytics 4 と BigQuery を連携した
- Next.js のコードには Google Tag Manager の初期化コードのみ入れる方針にする
- 例えばあるページの独自スコアリングを行いたい場合、タグマネージャーの変数やカスタムイベントで表現する方法と、既存のイベントから BigQuery で頑張って集計する方法があると考えている。まずはBigQueryでやってみて、どうしても表現が不足する場合に Tag Manager からのカスタムを検討する ほうに倒した。
方針
今
こうしたい
最後はタグマネージャーに一本化
タグマネージャーを通しておけばそこからいろいろ転送できる
いまもっとも一番参考になるやつ
併用について調べる
このあたりを読む。具体的な設定方法はこちらに誘導された。
えっ何タグマネージャー?もうわからなくなってしまった。
どうやらタグマネージャーを使って連携する方法もあるらしい
せっかくなので調べておく。タグマネージャーの画面に行き、開発環境用のコンテナを作成。そうするとポップアップが出現した。
指示に従って貼り付ける。このブログを参考にした。
head
<Head>
{/* Google Tag Manager*/}
<script
dangerouslySetInnerHTML={{
__html: `
(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','${GTM_ID}');
`,
}}
/>
</Head>
body
<Html lang="ja">
<Head />
<body>
<noscript
dangerouslySetInnerHTML={{
__html: `
<iframe
src="https://www.googletagmanager.com/ns.html?id=${GTM_ID}"
height="0"
width="0"
style="display:none;visibility:hidden"
/>`,
}}
/>
</body>
</Html>
トリガー?
これでどうやらトリガーするかどうかの扱いが Google Tag Manager 側に委譲されるっぽい。NextRouter によるクライアントサイドのページ遷移はどうなるの?という話はあるが、いったんこの状態で GA4 と連携してみる。
GA4 と GTMを連携
参考:
GTM > タグ > 新規 で Google Analytics 4 設定を選択。GA4 イベントはカスタムイベントを送信したいときに使うかもしれないらしい。今は設定しない。
- 測定ID:
G-
から始まるやつを入力 - サーバーコンテナに送信する: 空
サーバー コンテナに送信する
この GA4 設定に関連付けられているすべてのイベントを、Google アナリティクスに直接送信するのではなく、指定したサーバー コンテナの URL に送信すると、タグ マネージャーのサーバー コンテナで使用できるようになります。詳細
え、何、これ?このサイトが解説してくれています。要するにタグマネージャーのサーバーを経由するかどうかということみたい。
ナシでOK。ほかもとりあえず空で連携する。
トリガー
ひとまず App Pages ページビューを設定。なんか少ない気がするけどいいのか?設定したら保存する。
コンテナを公開
ここまで設定してコンテナを公開した。バージョン名はよくわからなかったので「お試し」としておいた。
これでGA4にイベントが飛ぶ?
ローカルで試してみる。
飛んだ!
GTMのプレビューモード & GA4のDebug View
イベントの中身を覗きたいのでプレビューとデバッグができるようにする。
まず、かんたんにできることとして、GTMのタグ設定で、GA4部分の「設定フィールドに」debug_mode: true を追加。
これで、GA4に対してすべてのイベントが デバッグモードで飛ぶ。ソースはここ。
GTM のプレビューモード
ヘッダバーにある「プレビュー」を押すと Tag Assistant が起動する。タグを埋め込んだサイトURLを入力して接続すると、プレビューモードでつなぐことができる。この時点で、デプロイ済みでないとプレビューできないということになるので、ローカルでもう少し確認発しやすくなるといいなと思った。ngrokとか使うしかないか。
プレビューモードでイベントが取れていることを確認。ページビュー、離脱クリック、ファイルダウンロードなどここで設定したデフォルトイベントは問題なく取れている模様。
GA4 のデバッグモード
この状態であればGA4のデバッグモードも利用できるはず。次の画面にいって、実際の画面操作とほぼリアルタイム(10秒後くらい)にイベントが飛んできている様子が確認できるかチェックする。
大丈夫そう。このふたつを使って、設定した内容がどうGTMに飛んできて、どうGA4に連携されているかを確認できそう。
参考
クライアントサイドのルーティングがある Next.js だとアレが気になる
history.push でもページビューをカウントしてほしい。
まず、history.pushでページビューイベントが発生しないケースがあるかチェック...なんだけど
なんか普通に履歴の変更にも反応して計測できているぽいので、ドキュメント側で調べてみる。ちなみに今の設定の状態は、debug_modeをtrueにした以外では特になにもしていない。GoogleTagManger と GA4 をAll Pages
でつないで GTM のタグをサイトに設置しただけ。
履歴変更についてのドキュメントを探すが…公式のドキュメントが見つけられない…このブログが一番理解できた。
リプライにざっくりまとめた。要するに GTMとGA4を連携していればhistoryChangeも勝手に計測してくれる。ありがたいですね。
GA4側「ブラウザの履歴イベントに基づくページの変更」を少し掘り下げ
GA4のイベントが自動で採取されることがわかったが、じゃあどういう条件で発動し、どういう条件では発動しないかを確認しておくのがよさう。ドキュメントあるかな…
マジで見つからない。どなたか、以下について、どういうときに page_view カウントされるか情報お持ちの方いらっしゃいましたら教えて下さい。
- gtm-historychange-v2
- ブラウザの履歴イベントに基づくページの変更
- page changes based on browser history events
自分で確認
この内容は筆者が手元確認したものなのであまり信用しないようお願いします。
操作 | gtm-historychange-v2の historyChangeSource |
GA4でpage_view カウントされるか |
---|---|---|
next/Link による遷移 | pushState | yes |
目次による#mokuji 移動 |
hashchange | no |
条件変更?type=all 移動 |
pushState | yes |
戻る(別のページへ) | replaceState | yes |
進む(別のページへ) | replaceState | yes |
という具合で、URLのハッシュ#
が変わる場合以外はすべてpage_viewとしてカウントされた。この事実がOKかNGかはチーム次第だと思うが、今の所こういう動きっぽい。クエリ?
でも page_view カウントされるのですね。
Google Tag Manager が発火する履歴に関するイベントには、
- gtm.historyChange
- gtm.historyChange-V2
がある。前者は、Google Tag Manger の トリガー > 履歴の変更 で明示的に指定すると計測されるイベントだ。一方 gtm.historyChange-V2
は Google Analytics4 による拡張イベントによって計測されるもの で、Google Tag Manager と Google Analytics 4 を連携している場合、Google Tag Manager 側で自動で採取され、GA4に送信される。
gtm.historyChange-V2
はデフォルトで有効になっており、無効とするためにはGA4の拡張計測機能で履歴ベースのページビューをOFFにする。
イベントの観察〜サイト内検索は検知できるか?
このイベントが収集されてほしい。デバッグビューで確認。
page_view
履歴の変更に対してどういうポリシーをとるか別途考える必要はあるものの、取れるか取れないかで言えば普通に取れる。問題なし。
scroll
ページでスクロールしたらとれる。イベントをドリルダウンするとpercent_scrolled
ということでページのどれくらいスクロールされたかもわかる。
離脱クリック click
ページ内に設置したツイッターのリンクを踏んだらとれた。
ユーザーが現在のドメインから移動するリンクをクリックするたびに記録されます。
らしいです。
サイト内検索 view_search_results
デフォルトでは、URL に次の 5 つのパラメータのいずれかが含まれているかどうかに基づいてイベントが記録されます。
q
s
search
query
keyword
構築しているサイトの検索フォームは、q=
でクエリを送信するタイプだったので問題なくこのイベントも取得できた。
動画エンゲージメント
- video_start
- video_progress
- video_complete
埋め込みYouTube動画が再生されると記録されるらしい。残念ながら計測したいサイトの埋め込み動画はイベントが発火されなかった。なんか動画の埋め込み方があるのかな。
ファイルダウンロード file_download
文字通り何かしらのファイルをダウンロードすると計測される。対象サイトでは問題なく計測された。
結果
動画再生以外のすべてのデフォルトイベントが意図通り計測された。
GA4 と BigQuery との連携
もうあと一歩です。まずは連携してみます。GA4のプロパティ設定>BigQueryのリンク設定から。
ストリーミングも有効にします。
データが流れてこない…?
ここを見ながら。少し待ったほうがいいのかな?
これなので少し待ちます。
一夜明けて
連携されてました!
GA4 と BigQuery の連携を深堀り
まず、データセットはこのような状態だった
※ストリーミングエクスポートオプションを有効にしています。
- events_intraday_ : 内部ステージングテーブルで、その日発生したセッションアクティビティのレコードが保持されていて、GA4でのイベント発生から数分以内にエクスポートされるらしい。すごいね。「速報」や「その日の一時的なトレンド」を追いかけるのに使えるかもしれない。
- events_ : 1日に1回、すべてのイベントがエクスポートされる。確定情報はこちらを使ったほうがよさそう。
疑問:events_
に連携されるのはどのタイミングなんだろう…?
カスタムディメンション考察 - そもそも GTM 連携している状況で GA4 にカスタム変数を飛ばすには
タグマネージャーと連携している状況で、そもそもカスタムディメンションをGA4で発火させるにはどうすればいいのか。
結論
すべての Page View に変数を仕込む場合。
- GTM側で変数を定義する
- GTM側で「GA4 設定」に Fields to Set を以下のようにする
Value に定数を入れることもできるし、「変数」で設定した内容になるよう設定できる。その場合は波括弧{{}}
で変数名を囲む。
- GA4 側で カスタム定義 > カスタムディメンション > カスタム ディメンション を作成 とする
ユーザープロパティ / パラメータは GTM 側で設定したパラメータ名と一致させる必要があります。これでOK。連携されるはずです。
定数・固定値ならこれでいいんだけど...
問題は Page View に正規表現などのギミックを載せて変数を載せたい場合。例えば以下のような変数を定義する。
残念ながらこれをGA4プロパティに設定しても正規表現が判定されることはない。元になっている 「Page Path」変数が、ページロード時の変数であり、History Change V2 のイベント時には変化しないため。トップページへ最初にアクセスすると、リロードしない限り・History Change で遷移する限り「Page Path」 は /
のままになる。
じゃあ、ということでビルトインの History Change 系変数を入れようとする。そうすると gtm.historyChange-v2
に変数がはいってこない。なぜか。おそらく gtm.historyChange-v2
は完全に GA4 のもので、今の所 GTM から干渉する手段がないのではないかと予想。
なので、計測したい対象のイベントをカスタムトリガーで飛ばし、そこに任意の変数を入れ込むのが今は良いのではないかと考えている。
カスタムトリガー、カスタムイベント考察
上記の gtm.historyChange-v2 の話に加えて、デフォルトイベントに変数を仕込む方法だと、例えば「あるURLに一致する場合」みたいな変数を作った場合、すべてのデフォルトイベントに対して変数が飛ぶことになる。それだと後々のレポートで判別しにくかったりするかもしれない(例えば、本来であれば特定のURL+クリックイベントに仕込みたい変数だった、みたいな話)
ということであるWebページをスコアリングするために、
- page_view じゃなくて score_page_view みたいなカスタムイベントを打ちたい
- カスタムイベントに独自データ (例えばページURLのスラッグどか)を入れたい
を検討する状況を考えてみる。データが増える気もするけどそこは区別優先でいいかな。こういうときはカスタムトリガー+変数のあわせ技がよさそうか。
[GTM]カスタムトリガーを設定
- トリガータイプ:Page View
- Some Page VIews
-
/[product_name]/coffee/[product_slug]
に反応させたい
従来のイベントをGTM+GA4で再現する方法を考察
- page_view
- あるページの平均滞在時間
これらを取得する方法を検討する。
page_view
これはそんなに難しくない。ただ、上記の理由で gtm.historyChange-v2 は現状スコアリング用の変数を入れ込むのが難しいので、新しく履歴の変更に反応するトリガーを作成し、そこで任意の変数を入れると良い。
あるページの平均滞在時間
問題はこれ。レポーティングAPIでいうところの ga:avgTimeOnPage
だ。GA4ならば BigQuery に連携できるのでクエリで抽出できなくもないとか…
でも副問合せを行うとどうしても抜け落ちる情報もでてくるし、単一のイベントで計測する方法はないだろうか。
やめたほうがよさそう
GA4 は BigQuery と連携できるので、まずはなんとか BigQuery のクエリで表現できないか模索して、どうしもむりぽなときだけカスタム変数、カスタムイベントを検討する方針がよさそう。