このブログにGoogle Analytics(GA4)を導入した。直接GA4のスクリプトを埋め込むのではなく、Google Tag Manager(GTM)経由で入れる構成にした。
構成
- サイト側には、GTMのコンテナID(
GTM-XXXXXXX)を埋め込んだスクリプトタグだけを置く - GA4への送信設定(測定ID、トリガーなど)は、GTMの管理画面(tagmanager.google.com)側でコンテナの中身として管理する
この分離のおかげで、GA4の測定IDを変えたり計測タグを追加したりしても、サイト側のコード変更・デプロイは不要になる。GTM管理画面で設定して「公開」するだけで反映される。
サイト側の実装
Astroの共通レイアウトに、PUBLIC_GTM_IDという環境変数が設定されているときだけGTMのスクリプトを差し込むようにした。
{
PUBLIC_GTM_ID && (
<script
is:inline
set: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','${PUBLIC_GTM_ID}');`}
/>
)
}
<body>直後にはnoscript用のiframeも同条件で差し込む。
ローカル開発やVercelのPreviewデプロイでアクセスしたときに、それが計測データに混ざってしまうのを避けるため、PUBLIC_GTM_IDはVercelのProduction環境にのみ設定し、ローカル・Previewでは未設定のままにしている。
GTMコンテナとGA4タグの関係
GTMのコンテナは、あくまで「箱」でしかない。
- コンテナ(
GTM-XXXXXXX): サイトに埋め込むのはこのIDだけ。中に何が入っているかはサイト側からは関与しない - タグ: コンテナの中身。「GA4にこの測定IDでイベントを送る」といった実際の計測設定は、すべてこのタグとして管理画面上で作る
つまり、コンテナを埋め込んだだけではまだ何も起きない。中にタグが入っていて、かつそのタグが公開されて初めてGA4への送信が始まる。
GA4向けのタグは、以前は「Google アナリティクス: GA4 設定」というタグタイプだったが、現在は**「Google タグ」**というタグタイプに統合されている。設定するのは以下の3つ:
- タグID: GA4の測定ID(
G-XXXXXXX) - トリガー: 「Initialization - すべての初期化イベント」
また、タグ名は動作に影響しないラベルなので何でもよい
ハマった点: 公開したのにタグが空だった
タグをPublishしていない状態で、https://www.googletagmanager.com/gtm.js?id=GTM-XXXXXXXを直接取得して中身を確認したところ、"tags":[]と、タグが1つも入っていない状態だった。
curl -s "https://www.googletagmanager.com/gtm.js?id=GTM-XXXXXXX" -o gtm_check.js
grep -o '"tags":\[[^]]*\]' gtm_check.js
Publishし直した後に同じコマンドで確認すると、tags配列にGA4向けのタグ("function":"__googtag"、vtp_tagIdに測定IDが入ったオブジェクト)が入っていることを確認できた。