【GTM仕組み理解】GTMでのGA4計測設定によって、なぜユーザの行動を計測出来るのか

# まえがき

対象読者：**GTM、GA4での計測設定はある程度理解しているがなぜ計測できるのかが理解できていない人**

GTMでのタグ・トリガー・変数とは何か？などの基本的なところについては他記事にて解説されていることが多いので割愛します

**GTMがどのような働きをしているのか、ユーザの行動がどのような仕組みで計測されるのか**という点を、実際のユーザ行動・ブラウザの動きと対応させることでイメージが付けられるように説明を試みます。

※厳密には異なるという点もあると思いますので、その際はご指摘いただけますと幸いです。
# 前提となる知識

- GTMの基礎知識
    - トリガー、変数、タグなど
- GA4の基礎知識
- ウェブページが表示される仕組み
    - ブラウザについて
- JavaScriptとは何か？
- dataLayerについて

これらの知識は深く理解してなくてもよいですが、理解する上で必要になるので適宜調べて下さい。これらの情報はネット上に溢れかえっているので困らないと思います。

その上で2つ前提を共有しておきたいことがあり、それがdataLayerとdataLayerにデータが送られるタイミングです。

## dataLayerとは

dataLayerとはブラウザ上のデータを格納している箱だと思ってください。GTMはこのdataLayerにデータが追加されたことを検知します。
例えば、要素AがクリックされたことをトリガーにするGA4イベントタグを作成したとします。この際は、要素に関わらずクリックという行動が起こるとclickイベントを発生させ、dataLayerにクリックに関する情報を格納するようになっています。その中で、送られたクリックに関する情報がトリガーに設定したものと一致したときのみGA4イベントタグが配信され、GA4へデータ送られる仕組みになっています。
このようにGTMはdataLayerの情報を元にGA4へデータを送ります。そのため、GTMを理解するにあたってdataLayerの理解は必須となります。

## dataLayerにデータが送られるタイミング

先ほどの例でも挙げたように、何かイベントが行われた時dataLayerに値が格納されます。そしてそのdataLayerへの値の格納をGTMは検知します。これを頭に入れておいてください。
ページの読み込み時、クリックした時など何かの処理が行われた時にdataLayerへ値を格納するというようにJavaScriptで記述されているとイメージしてください。


:::note info
**理解してほしい前提のまとめ**

- ブラウザ上にデータを格納する箱であるdataLayerがある
- ページ上での様々なイベント発生時にそのdataLayer値が格納されるようにJavaScriptは記述されている
- イベントの発生及びdataLayerへの値の格納をGTMは検知する
- GA4に送ることが出来るデータは基本的にはdataLayerに格納されている値のみ
:::

# 今回考える状況

➀ GA4とGTMのアカウントとGA4のデータストリーム、GTMコンテナを作成済み。
そして、ウェブサイトにGTMスニペットを設置している。

➁ GTMにてGA4初期設定タグとGA4クリックイベントタグを作成している。
設定は以下の通り。

A
タグ名：GA4初期設定タグ
タイプ：Googleタグ
測定ID：<GA4の測定ID>
トリガー：Initialization - All Pages 初期化

B
タグ名：GA4クリック
タイプ：GA4イベント
イベント名：test_click
測定ID：<GA4の測定ID>
トリガータイプ：すべての要素
条件：ID 等しい testID

③ ➀➁の初期設定完了後、ユーザがウェブサイトに訪問し、クリックイベントを発生させる

# 全体像

![GTM計測説明用2.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2998651/d19d7ce6-a496-4a28-a438-bfbbc91c96aa.png)


## 1. ユーザがウェブサイトに訪問

### 1-1. webサーバへデータをリクエストし、レスポンスを受け取る

ユーザがウェブサイトに訪問するためにブラウザがウェブサーバにリクエストを送ります。
サーバにリクエストを送って、サーバからレスポンスを返してもらいます。そのレスポンスの中身がHTMLファイルなどです。
ブラウザはレスポンスの中身のHTMLなどを解釈して描画します。HTMLファイルを上部から読み込んでいき必要があればサーバに問い合わせ、データを取得します。JavaScriptコードも順次実行していきます。
HTMLファイルにGTMスニペット(JavaScriptコード)を設置したと思います。このスニペットも読み込まれて処理されることになります。

### 1-2.GTMスニペットが読み込まれ、GTMで設定したタグの配信準備が行われる

スニペットは以下のようなものです。

```javascript:GTMスニペット
<!-- Google Tag Manager -->
<script>(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-ABCDEFGH');</script>
<!-- End Google Tag Manager -->

```

このコードが何をしているのかをまとめると以下です。
- Google Tag Manager の初期化
    - dataLayer配列を初期化
    - dataLayerにgtm.jsというイベントを記録
        - GTMがいつ開始されたかを記録
- Google Tag Manager スクリプトの読み込み
    - ページ内の最初の\<script>を取得
    - 新しい\<script>要素を作成
    - dataLayer名がデフォルトのdataLayerと異なる場合に、URLパラメータを作成
    - スクリプトを非同期で読み込むように設定
    - GTMのスクリプトURLを設定
    - 作成した\<script>要素をページの先頭に追加

これは以下のスクリプトを生成してスニペットの上部に追加していると理解出来ます。

```javascript:GTMスニペット
<script async="" src="https://www.googletagmanager.com/gtm.js?id=GTM-ABCDEFGH"></script>
```

このスクリプトが追加される目的を一言で言うと、**GTMとウェブサイトを連携させるための準備**となります。
もう少し踏み込むと、この**scriptが追加されることによりGTMでの設定内容が記載されたJavaScriptファイルをブラウザ側で読み込める**ようになっています。GTM-ABCDEFGHの箇所にてGTMのコンテナを特定しています。
GTMのUI上での作業によってこのJavaScriptファイルが編集されているイメージです。
ちなみにこのJavaScriptファイルは検証ツールのSourcesタブにて確認することも出来ます。


参考
[Google Tag Managerのスクリプトを噛み砕いて理解する](https://qiita.com/KokiSakano/items/ef8654c82b05ba203479)

### 1-3.GTMで設定したトリガーがイベント・dataLayerの値をチェックできる状態になる

GTMスニペットが読み込まれ、GTMが生成したJavaScriptファイルを読み込むと、発生する各イベントを検知してタグを配信する準備が整います。
発生する各イベントを確認してトリガーの条件に当てはまるかをチェックします。

### 1-4.GTMにて初期設定としてJavaScriptに記載された自動イベントが発生する

GTMスニペットが読み込まれ、GTMサーバにあるJavaScriptファイルが実行されると以下イベントが発生します。
JavaScriptファイル内にイベントを発生させる記述があるため、イベントが発生します。
これらは処理の各段階でイベントを発生させており、処理内容は名前から推測出来ると思います。
- gtm.init_consent
    - ユーザの同意を確認
- gtm.init
    - 初期化を行う
- gtm.js
    - コンテナを読み込む
- gtm.dom
    - DOMを読み込む
- gtm.load
    - ページを読み込む

### 1-5.GA4初期設定タグが配信される(1-4のgtm.initのタイミング)

今回はGA4初期設定タグに初期化トリガーを設定しています。これはgtm.initというイベントが発生したときにGA4初期設定タグを配信するという設定を意味します。
※厳密にはgtm.initのタイミングとは少しずれるらしいです
そのため、gtm.initイベントが発生した直後にGA4初期設定タグが配信されます、これはGA4にpageviewイベントを送るということを意味します。このpageviewイベントにはpagelocationなどの付加情報がイベントパラメータとして付与されて送られます。

以上のような流れでユーザの訪問の記録であるpageviewが計測されます。

## 2.ユーザがtestIDというIDを持つ要素をクリック

ユーザがページに訪問し、pageviewが発生した後の話となります。
例えば以下のような要素をクリックしたときです。

```javascript:GTMスニペット
<div id="testID">これはtestです</button>
```

### 2-1.クリックイベント時にdataLayerにclickイベントが記録される。
ユーザがクリックした際に、clickイベントが記録され、以下の写真ようなものがdataLayerに格納されます。
elementId, elementTargetなど組み込み変数として追加したものが基本的にはdataLayerに格納されるイメージです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2998651/b677919e-e96b-45f0-b9a0-fe2959b1a2b1.png)

### 2-2.clickイベントにてdataLayerに格納される値がトリガーと合致するかチェックが入る

今回、以下のようなトリガーを設定しています。

タグ名：GA4クリック
タイプ：GA4イベント
イベント名：test_click
測定ID：<GA4の測定ID>
トリガータイプ：すべての要素
条件：ID 等しい testID

このような場合、event = "gtm.click" and elementId = "testID"という条件に合致するものがdataLayerに格納されたことをGTMは検知してタグを配信する仕組みになっています。写真の例では、elementId = "testID"のためトリガーが発火しGA4クリックタグを配信します。これはGA4にtest_clickイベントというデータが送られることを意味します。
もしelementIdの値が異なっていれば、GA4クリックタグは配信されません。

このようにして、ユーザのクリックが計測されます。

# まとめ

以上のような流れでGTM経由でのGA4計測が行われます。少しはイメージが付いたのではないでしょうか？

私が気になり自分なりに考えたGTMの仕様についておまけとして以下に記載します。
自分の仮説が合っているかが分からないので参考程度に見ていただけると幸いです。

## 私が以前直面した疑問とそれに対する仮説
- データレイヤは配列になっている。この配列のどの範囲のデータが取得できるのか
    - 一言で言うと、配列がまとめられて一つの統合データとされている
    - 重複の無いdataLayerキーと値を残し、重複があれば更新していく仕様になっている
        - 例えばeventというキーの値は常に更新されていくなど
- clickイベントなどにてdataLayerに格納されるデータの種類や数はどのように決まるのか？
    - GTMが用意している組み込み変数がclickイベント時にdataLayerへ格納される仕組みになっている
    - また、GA4イベントタグ作成時にイベントパラメータに設定する変数もdataLayerに格納される
- Google タグで送られるpageviewイベントはdataLayerにデータを格納せずともGA4に直接データを送っている
    - dataLayerの値をGA4に送ったわけではない