昨今ではすっかりスマホが普及して、インターネットもスマホを前提としたサイトが増えてきました。
それに伴ってよく見かけるようになったのが、スクロールしても追従してくる、画面下部に表示されてるバナーなどを配置したレイアウトです。
特に広告などから流入するランディングページなどでは、一般的に「ページ本体には商品宣材コンテンツが表示されて」「興味を持ったユーザーはフローティングバナーをクリックして次のステップへ」といった作りになっていることが多いですよね。
そんなランディングページの成果を計測する際の一つの指標として、例えば「どのコンテンツを読まれてる際にフローティングがクリックされたか」を知りたかったりしないでしょうか?
必要な考え方:「要素の表示」トリガーとdataLayer.pushで最新の情報を保持
前提として、GTMの機能としては「今何が表示されているか」を取得することはできません。
……一応、ユーザー定義変数にある「要素の視認性」変数で特定要素の状況は取得できるのですが、「やろうと思えばできないこともないけどかなり非現実的」といった具合ですね。
1変数につき1要素の状況しか取得できないため、GTM内の設定がやばいことになります。
「今何が表示されているか」は、取得することができません。
しかし「〇〇が表示された」は、要素の表示トリガーで感知することができます。これを使います。
そこで考え方としては、こうです。
各ブロックが表示される度に「いま表示されたブロック」を変数として更新し続けることができれば、その時点で「最後に表示されたブロック=いま表示されているブロック」が分かるはず。
具体的な方法
- 「いま表示されているブロック」を示す変数を、データレイヤー変数で用意
変数のタイプ:データレイヤー変数
データレイヤーの変数名:view_content_block
(※任意に変更OK)
データレイヤーのバージョン:バージョン2
(デフォルト)
デフォルト値を設定:ON
デフォルト値:(first view)
(※ページ最上部時に計測したい値名。任意に変更OK) - 「各ブロックが表示されたら反応」な要素の表示トリガーを用意
トリガーのタイプ:要素の表示
選択方法:(ページによる)
このトリガーを起動するタイミング:各要素が画面に表示されるたび
視認の最小割合:(ページによる)(指定要素がブロックであれば10~20などの小数値、見出しであれば100などの大数値)
画面上での最小表示時間を設定:ON
2000
(※任意に変更OK)
DOM の変化をモニタリング:OFF
(※AJAXやSPA、Lazy Loadなどがあるページの場合はON)
このトリガーの発生場所:一部の表示イベント
(対象ページを指定する条件を設定。サイト内全体が対象であれば「すべての表示イベント」) - 組み込み変数の
Click Element
変数を有効化 - [1]の変数をアップデートするカスタムHTMLタグを、配信トリガーに[2]を付けて登録
タグの種類:カスタムHTMLタグ
HTML:<script>
dataLayer.push({'view_content_block': '(ブロック名)'});
</script>
※データレイヤー変数名は[1]で登録した変数のデータレイヤー変数名
※変数値の取得方法はページによって要調整
document.write をサポートする:OFF
配信トリガー:[2] - フローティングバナークリックを計測するタグの計測値に[1]の変数を設定
おおまかな設定というか考え方については、この流れです。
ですが実際のところ、肝心のトリガーおよび変数の設定はページの構成(主にHTML)によって大きく変わります。
すこし例を挙げてみます。
前提条件となるページ構成
大前提として、今回ご紹介している方法では
- フローティングバナー(スクロールしても画面内に追従してくるバナー)がある
- 1カラム構成のページレイアウトになっている
必要があります。
なおレスポンシブデザインなサイトで、PC版表示時には複数カラムレイアウトになる、みたいなケースも多いと思います。
その場合はトリガー設定等で対処する必要があるので、ご注意ください。
(例えばユーザーエージェントを参照してスマホ以外の時は反応しないようにする、など)
さて、実際の「要素の表示」トリガー(の選択方法)と「表示ブロックを取得するカスタムHTMLタグ」(のデータレイヤー変数値)の設定は、ページの作りによって千差万別です。
主にHTMLの構造毎に異なりますので、HTMLやCSSの知識が多少必要になる点はご注意ください。
もっとも汎用的なパターンであれば、次のようになります。
方法:ブロックごとに見出しタグが設置されている場合
例えば、HTMLの文書構造が、下記のようになっているページの場合です。
<div>
<section>
<h2>ブロックA</h2>
</section>
<section>
<h2>ブロックB</h2>
<section>
<h3>ブロックB-1</h3>
</section>
<section>
<h3>ブロックB-2</h3>
</section>
</section>
<section>
<h2>ブロックC</h2>
</section>
</div>
section
タグで各ブロックが定義されていますよね。
なおsection
タグでなくても、例えば<div class="block">
みたいに「ブロック用」のclass
が定義されている場合なども、同様です。
そして各ブロックにはブロック名を示す(はず)の見出しが、それぞれ設置されています。
このようなケースであれば、各見出しを対象にすることで、表示ブロックの更新もスムーズにできます。
- 「要素の表示」トリガーの「選択方法」
- 選択方法:
CSSセレクタ
- 要素セレクタ:
h1, h2, h3, h4, h5, h6
- 視認の最小割合:
100
- ※実際にプレビューで試して、トリガーが反応しなかった場合は数値を減らしてください。
- 選択方法:
- 「表示ブロック更新」のカスタムHTMLタグ
- カスタムHTMLタグ:
- ※組み込み変数のClick Text変数を有効化してください。
<script>
dataLayer.push({'view_content_block': {{Click Text}} }); // 各見出しタグ内のテキストを取得
</script>
- ※組み込み変数のClick Text変数を有効化してください。
- カスタムHTMLタグ:
もし見出しタグ内がテキストではなく画像を設置している、などのケースがある場合は、上記では(画像のalt属性値は)取得できません。
その場合は「GTMでクリックされたリンク内の画像のaltを取得する方法」 記事のJSを参考に、アレンジください。
方法:その他
さて、HTMLはページによって本当にまちまちですので、方法も千差万別です。
ただ設定方法の要点としては、
- 「要素の表示」トリガーで「各ブロック」または「ブロック名として抜き出したい要素」をCSSセレクタで指定する
- Click Element変数に「『要素の表示』トリガーで指定した(反応した)要素」がまるまる格納されるので、カスタムHTMLタグでJavaScriptを書き、「要素の表示」トリガーで指定したのがブロックであれば
querySelector
関数(指定したCSSセレクタに最初に合致した要素を返す)を使ったり、または「要素の表示」トリガーで指定したのが「ブロック名として取得したい要素」であればinnerText
関数(対象要素が内包するテキストを返す)などを使うことで、「ブロック名」として抜き出したい情報を抜き出してdataLayer.pushでデータレイヤー変数をアップデートする
という点です。
CSSセレクタの基本
- CSSに置いて「要素を指定する」ための書式。
- タグ名(例:
h1
) ⇒ 任意のHTMLタグのHTML要素(例:h1タグ) - .class名(例:
.block
) ⇒ 任意のclassを付与されているHTML要素(例:class属性にblockがある要素) - #id名(例:
#content
) ⇒ 任意のidを付与されているHTML要素(例:id="content"
な要素) - , ⇒ 複数条件を書く際の区切り文字(例:
h1, h2, h3, h4, h5, h6
⇒ h1タグもしくはh2タグもしくはh3タグもしくは……) - (半角スペース) ⇒ 親子構造を指定(例:
.block h1
⇒ blockというclassが付与された要素内のh1タグ)
ざっくりとした今回のJSの基本
- ユーザーのブラウザ内で処理されるプログラミング言語。
;
⇒ 行の最後に書く。行(というか処理)の末端を意味する.
⇒ 親子関係や処理対象を示す。(例:A.B ⇒ Aに属するB){{Click Element}}
⇒ Click Element変数の値を参照。「要素の表示」トリガーであれば、トリガーが反応した対象のHTML要素が入るquerySelector("CSSセレクタ")
⇒ 対象要素内から、()
内で指定したCSSセレクタに合致した最初の(先頭の)HTML要素を返す。(例:{{Click Element}}.querySelector('h1, h2, h3, h4, h5, h6')
⇒ 「要素の表示」トリガーが反応した要素内の先頭の見出しタグのHTML要素を取得)innerText
⇒ 対象要素内のテキストのみを抜き出して取得(例:{{Click Element}}.querySelector('h1').innerText
⇒ 「要素の表示」トリガーが反応した要素内の先頭のh1タグ内のテキストを取得)
CSSセレクタやJSの詳しい解説をすると本記事の趣旨を外れて膨れ上がってしまうため割愛しますが、もし身近にいらっしゃれば、エンジニアの方などにご相談いただくと解決するかもしれません。
今回の手法の注意点
いちばん大きな注意点としては「ページ(のHTML構造やレイアウト)によってできるできない」が分かれる点です。
つまり、少なくとも対象ページのHTML構造についてきちんと理解していないと、使用は難しいでしょう。
また「要素の表示」トリガーで「指定した要素が表示される度に次々『今表示されてるブロック』をアップデートし続ける」ことで対応する形です。
そのため、欠点として「複数の対象要素が画面内に同時に出た場合、後から出た要素のブロック名」にアップデートされます。
つまり、精度がそこまで高いわけではありませんので、この挙動の仕様を把握したうえで「目安としての」計測にご利用ください。
今回はこんな、「デフォルトでは実装されてないけどやり方を工夫したらなんとかなりそう」な手法のご紹介でした。
題材としてはフローティングバナーを取り上げていますが、実のところ本記事の最大の要点は「要素の表示トリガーっていろいろと応用範囲大きいですよね」というところですね。
他にもいろいろとできそうですし、「こういうことやったらすごいことできた!」みたいなことがあればぜひ皆さんも情報発信いただけると、ほっこりします。