Google タグマネージャー(GTM)を利用して計測を行っていると、「dataLayerには設定していないはずの値が、なぜかGA4に計測されている」という現象に遭遇することがあります。
特に、ページ遷移をせずに同一ページ内で複数回イベントを送信する場合などに、このような事象が発生することがあります。実際にdataLayerを確認してみても、該当するイベントにはその値が設定されていません。
では、なぜ設定していない値がGTMで取得され、計測されるのでしょうか。
今回は、簡単なdataLayerを使って、設定していない値が計測される仕組みと、意図しない値の計測を防ぐための対応方法について解説します。
dataLayerに設定していない値が取得される?
まずは、次のdataLayerを実行してみます。
dataLayer.push({
event:'test_click1',
param_key1:'param_val1A',
param_key2:'param_val2A',
});
このdataLayerには、param_key1とparam_key2の2つのパラメータを設定しています。
GTMのGA4 イベントタグは以下のような設定です。

Google アナリティクスの送信データをGTMのプレビューモードで見てみましょう。

param1とparam2に、dataLayerで指定した値が反映されています。
続いて、次のdataLayerを実行します。
dataLayer.push({
event:'test_click2',
param_key1:'param_val1B',
});
今度はparam_key1だけを設定し、param_key2は設定していません。
ブラウザの開発者ツールなどからdataLayerを確認すると、2回目にpushしたオブジェクトにも、当然param_key2は存在しません。

そのため、「2回目のイベントではparam_key2の値は計測されない」と思うかもしれません。
では、GA4の送信データを見てみます。

赤枠にあるように、2回目のイベントでも、1回目に設定したparam_val2Aが計測されています。
なぜ、このようなことが起きるのでしょうか?
dataLayerには値がないのになぜ取得される?
まず確認しておきたいのが、ブラウザ上のdataLayerです。
先ほどの2つのdataLayerを実行したあとに、イメージとしては次のようなオブジェクトがそれぞれ格納されています。
▼1回目
{
event: 'test_click1',
param_key1: 'param_val1A',
param_key2: 'param_val2A',
}
▼2回目
{
event: 'test_click2',
param_key1: 'param_val1B',
}
ここで重要なのは、2回目のdataLayerにparam_key2が追加されているわけではないという点です。2回目にpushしたオブジェクトを確認しても、param_key2は存在しません。
では、なぜGTMではparam_val2Aが取得されるのでしょうか。
GTMはdataLayerにpushされた情報を順番に処理し、GTM内部に値を保持します。
1回目のdataLayerをGTMが処理すると、GTM内部では次のような状態になります。

その後、2回目のdataLayerがpushされます。
ここではparam_key1に新しい値が設定されているため、
param_key1 = param_val1B
に更新されます。
一方、param_key2については何も設定されていません。したがって、2回目のdataLayerをGTMが処理すると、GTM内部では次のような状態になります。

このように、2回目のdataLayerにはparam_key2が含まれていなくても、GTM内部には1回目に設定したparam_val2Aが残っているため、データレイヤー変数から参照できます。
つまり、ブラウザ上のdataLayerと、GTMがその時点で参照できる値は必ずしも同じではありません。
今回の事象を理解するうえで重要なのが、「値を設定しない」ことと「以前設定した値を消す」ことは違う
という点です。
2回目のdataLayerでは、
dataLayer.push({
event: 'test_click2',
param_key1: 'param_val1B',
});
としており、param_key2そのものを記述していません。
しかし、これは「param_key2を削除する」という指示ではありません。単純に今回のpushではparam_key2について何も指定していないだけです。
そのため、1回目のイベントで設定した値がGTM内部に保持されていれば、その値を引き続き参照できることがあります。
これは同じページ内で複数回イベントを送信する場合に注意したいポイントです。
ページ遷移が発生すれば、新しいページの読み込みによってdataLayerやGTMの状態も基本的には新しくなります。一方、ページ遷移を伴わずにイベントだけを繰り返し送信する場合は、同じGTMの状態のままdataLayerへのpushが繰り返されます。
そのため、前のイベントで使用した値が後続イベントでも参照される可能性があります。
不要な値を残さないためには?
前のイベントで設定した値を後続のイベントで使用したくない場合は、不要な値を明示的にリセットする必要があります。
例えば、param_key2をクリアするのであれば、値を明示的にリセットします。
値を個別にリセットする場合は、対象のパラメータに以下のようにundefinedを設定します。
dataLayer.push({
event: 'test_click2',
param_key1: 'param_val1B',
param_key2: undefined
});
param_key2にundefinedを設定すると、GTMでparam_key2を参照した際の値もundefinedになります。

undefinedの値はGA4への送信データには含まれないため、以下のとおり、1回目に設定したparam_val2Aが2回目のイベントで送信されることを防げます。

ただ、複数のパラメータがあった場合、一つ一つにundefinedを設定することになりますが、非常に手間です。
このような場合は「名前空間(ネームスペース)」を使い、関連する値を一つのオブジェクトにまとめる方法があります。名前空間は、関連する値を共通の名前の配下で管理し、ほかの値との名前の衝突を避けるために使われる考え方です。名前空間を使うことにはさまざまなメリットがありますが、今回のようなケースでは、関連する値をまとめてリセットできることもメリットの一つです。
厳密にいうと、JavaScriptには「名前空間」という専用の仕組みはありません。オブジェクトを使って関連する値をひとまとめにすることで、名前空間のような構造を疑似的に作っています。……と、細かい話はこのくらいにして、ここではわかりやすく「名前空間」と呼ぶことにします。
例えば、次のように個別に設定していたパラメータがあるとします。
dataLayer.push({
event: 'test_click',
param_key1: 'param_val1',
param_key2: 'param_val2',
param_key3: 'param_val3',
param_key4: 'param_val4',
param_key5: 'param_val5'
});
これをparamという名前空間にまとめると、次のように記述できます。
dataLayer.push({
event: 'test_click',
param: {
key1: "param_val1",
key2: "param_val2",
key3: "param_val3",
key4: "param_val4",
key5: "param_val5"
}
});
paramという一つのオブジェクトの中に、key1からkey5までの値をまとめているのがポイントです。
名前空間を使うメリットの一つが、関連する値をまとめてリセットできることです。
例えば、param配下の値をすべてリセットしてから新しい値を設定する場合は、次のようにします。
dataLayer.push({ param: null });
dataLayer.push({
event: 'test_click',
param: {
key1: "param_val1",
key2: "param_val2",
key3: "param_val3",
key4: "param_val4",
key5: "param_val5"
}
});
dataLayer.push({ param: null });を実行することで、GTMが保持しているparamを一度リセットします。その後に新しいparamオブジェクトをpushすることで、前回のparam配下の値を引き継がず、今回必要な値だけをGTMから参照できるようになります。
▼1回目
dataLayer.push({ param: null });
dataLayer.push({
event: 'test_click',
param: {
key1: "param_val1",
key2: "param_val2",
key3: "param_val3",
key4: "param_val4",
key5: "param_val5"
}
});
▼2回目
dataLayer.push({ param: null });
dataLayer.push({
event: 'test_click',
param: {
key1: "param_val1",
key2: "param_val2"
}
});
1回目のイベントではkey1からkey5までを設定しています。
2回目のイベントでは、まずparamをnullにして一度リセットし、その後、今回必要なkey1とkey2だけを設定しています。
これにより、key3からkey5までの値を一つずつundefinedに設定する必要がありません。なお、paramをnullにする処理は、意図しない値の引き継ぎを防ぐための「おまじない」として、毎回入れておくとよいでしょう。
このような「名前空間を一度リセットしてから新しい値を設定する」実装は、GA4のeコマースでも使われています。
dataLayer.push({ ecommerce: null });
dataLayer.push({
event: 'view_item',
ecommerce: {
currency: 'JPY',
value: 1000,
items: [...]
}
});
GA4のeコマース実装例でこの1行を見たことがある方もいるのではないでしょうか。
currency、value、itemsなどの関連する値がecommerce配下にまとめられているため、ecommerceをnullにすることで、以前設定したeコマース関連の値をまとめてリセットできます。
つまり、ecommerce: nullも、ここまで説明してきた「以前の値を残さないためのリセット」と同じ考え方です。
まとめ
dataLayerに設定していない値がGA4に計測される仕組みと、その対応方法について解説しました。
特に注意したいのが、同一ページ内で複数回イベントを送信し、同じパラメータを使い回す場合です。次のイベントで値を設定しなくても、以前の値がGTMに残り、参照されることがあります。
「値を設定しない」ことと「以前の値を消す」ことは違います。
意図しない値の引き継ぎを防ぐため、関連する値をオブジェクトにまとめ、dataLayerをpushする前にnullでリセットする処理を「おまじない」のように入れておくとよいでしょう。
GA4のeコマースで使われるecommerce: nullも、同じ考え方によるものです。



![[GA4]AIを活用して計測内容をわかりやすく確認する方法](https://ayudante.jp/wp-content/uploads/2025/10/GA4.png)




