dataLayerへ値を渡す記述を.pushで統一する方法

2017年02月07日
ライター:畑岡 大作

ページ側(HTML側)からGoogleタグマネージャへ値を渡す方法として、メジャーなものとしてデータレイヤー変数があります。
しかし公式のヘルプを読んでみると、データレイヤー変数へ値を渡すための書式には「=を使った代入」式と「.pushを使った挿入」式の2種類が混在して取り上げられていたりして、しかも適切なタイミングで使い分けなければきちんとした値の受け渡しができないようです。
これはいささかわかりづらいので、どのタイミングでも使用できる記述について取り上げてみました。

  1. データレイヤー変数とは
  2. 値の渡し方は「=」と「.push」の2種類
  3. どんな場合でも「.push」で統一するための方法 ←本題
  4. オマケ:iframe内から親frameのdataLayer.pushする方法

データレイヤー変数とは

データレイヤー変数というのはGoogleタグマネージャ上で設定できる変数の1種類ですが、その内容をざっくりと説明すると「ページ側からデータを受け渡しするのにGoogleタグマネージャが推奨している変数の種別」です。
ツール側が推奨していることもあり、規定の書式で出力すればGoogleアナリティクスのeコマース計測タグなどで難しい設定をしなくても自動で値を利用してくれたりするなどの特典があります。

GoogleタグマネージャはWebページで動作する際、dataLayerというJavaScript変数内へ様々なデータを一時的に格納し、参照しています。
このdataLayer変数にはGoogleタグマネージャが自動的に追加や取得した変数のデータが格納されますが、意図的にHTML上から「dataLayer変数へ値を渡す」JavaScriptを動作させることで「Googleタグマネージャへデータを渡す」ことができます。そしてその渡されたデータを変数として参照可能にしたものがデータレイヤー変数というわけです。

「データレイヤーの変数名」で指定した名前を持つデータレイヤー変数の値を参照する「データレイヤー変数」
データレイヤー変数名を設定することで、dataLayerというJS変数の中の指定した項目が持っている値を参照できるようになります。

データレイヤー変数はもっとも「意図的にWebページ側からGoogleタグマネージャへデータを渡したい場合」に使われることの多い変数です。

あるタグやトリガーで利用したいと思ったデータが変数として登録できない場合、何らかの手段でGoogleタグマネージャへデータを渡すためにWebページ側を改修する必要が出てきます。
しかし例えば「URL」変数で参照できるURLはそもそもそう簡単に変えていいものではありませんし、「DOM要素」変数で取得できるbody内要素(divタグやらspanタグやらの特定HTMLパーツ)は基本的にユーザーへ表示させるもののため、Googleタグマネージャへデータを渡すためだけにページ内へブロックなどを追加するのもはばかられます。

そういった際に利用されやすいのが、画面の表示上ではユーザーへ特に影響が出ないデータレイヤー変数なのです。
また、データレイヤー変数であればソースを見たときに一目で「データレイヤー変数である(=Googleタグマネージャで利用しているソースである)」ということがわかる点もメリットです。

値の渡し方は「=」と「.push」の2種類

具体的にデータレイヤー変数へデータを渡す手段としては、JavaScriptで以下どちらかの処理を行います。
下記を()内の例で処理した場合、「test」というデータレイヤーの変数へ対して「abc」という値が渡されることになります。

<script>
dataLayer = [{'データレイヤー変数名(例:test)': '渡したい値(例:abc)'}];
</script>
<script>
dataLayer.push({'データレイヤー変数名(例:test)': '渡したい値(例:abc)'});
</script>

さて上記の通り、値を渡すための書式は2種類あります。
それぞれどんな違いがあるのかというと、動作可能なタイミングが異なっています。

書式 ページ内で一番最初に
出てきた場合
ページ内で二番目以降に
出てきた場合
dataLayer = [{~~}]; 動作する エラー動作になってしまう
dataLayer.push({~~}); JSエラーになってしまう 動作する

ページ内で一番最初にdataLayerをいじる場合は「=」で、二番目以降にいじる場合が「.push」となります。
というのも、JavaScriptのルールとして「『=』は値を『代入』」するためのもの、「『.push』は値を『追加』」するためのもの、という違いがあるからです。

ページ内で一番最初に出てきた場合、まだdataLayerというJS変数は存在していません。
存在していないので「追加」しようとしても追加先が見つからないため、JSエラーになってしまいます。

そして二番目以降に出てきた場合、すでにdataLayerというJS変数は「一番最初に出てきた際に定義されたデータを持って」存在しています。
しかし「代入」してしまった場合、その直前まで持っていたデータを上書きで消してしまうため、Googleタグマネージャが予期せぬ動作をしてしまいます。

最初に=はOK、.pushはNG。2度目以降に=はNG、.pushはOK。
ページ内で記述する位置に応じて書式を変えなければなりません。
なお、GTMスニペットタグも内部でdataLayerの定義を行っていますので、スニペットタグよりも前か後か、も気にする必要があります。とてもややこしい。

そういった理由もあって、前述のように「ページ内で処理される順番」によって書式を使い分けなければなりません。
でもこれって不便ですよね? 記述位置を意識せずにうっかり不適切な書式で記述してしまうだけで、エラーになってしまうのはとても危険です。

ですので、ページ内の最初であっても二番目以降であっても何の問題もなく動作する書式に変えてしまいましょう。

どんな場合でも「.push」で統一するための方法 ←本題

以下の書式にすることで、ページ内に出てくる順番を意識する必要がなくなります。
2行目の箇所(色の変わっている行)がポイントです。

<script>
window.dataLayer = window.dataLayer || [];
dataLayer.push({'データレイヤー変数名(例:test)': '渡したい値(例:abc)'});
</script>

やっていることは簡単で、「すでにdataLayerというJS変数があったらその値を引き継いで、まだなければ値を空の状態で作る」という処理を行っています。
つまりページ内の一番最初で.pushを使ってはいけない理由が「dataLayerが存在していないから」だったのなら、「なければ作って」しまえば何も問題が起きなくなる、という考えですね。これでページ内の記述位置の順番を問わず、上記の書式で統一することができます。

eコマース計測などを実装したり、また各種広告タグなどでページ側へデータ出力をしようとすると、データレイヤー変数の記述がページ内に増えてきたりします。
その記述の追加を行うのが書式の仕様について把握している依頼者当人であれば大丈夫だと思いますが、しかし実際にページ側を改修するのが別の担当者へ依頼しなければならない場合などによく起こるトラブルが「書式が不適切で正常に動作しなくなる」というものです。

こういった運用面での問題を回避するため、データレイヤー変数の出力に関しては書式を統一して担当者へお渡しするようにされると良いでしょう。

オマケ:iframe内から親frameのdataLayer.pushする方法

iframeなどで設置している内部ページについて、PV計測などをさせないためにGoogleタグマネージャのスニペットタグを設置していない場合などもあると思います。
そのようなiframe内のページでdataLayer.pushをしようとしても、iframe内ではdataLayerが存在していないため動作させることができません。そういった場合は自frame内ではなく、iframeを設置している外側の親ページで利用しているdataLayerへ対して、値を渡す必要があります。

親フレームへ値を渡したい場合は、以下の記述で行うことができます。

<script>
window.parent.dataLayer.push({'データレイヤー変数名(例:test)': '渡したい値(例:abc)'});
</script>

そう頻発するケースではありませんが、困った際は上記の書式を思い出してみてください。

この記事を書いた人
畑岡 大作
畑岡 大作
マークアップエンジニア

マークアップエンジニアとして活躍しながら昨今はGTMのスペシャリストに。日本初となる書籍を出版し、多くの顧客サイトのGTM設計、運用、アドバイスなどを行う。セミナー登壇も多数。好きな物はラノベ、ゲームからラーメン、万年筆(のインク)と幅広い。

最近書いた記事
著書