背景
Google Analytics Standard版のトラッキングデータをBigQueryにためてLookerで分析をしたい 01にて、SPAで実装されたWeb Siteにカスタムディメンションで任意の情報をGoogle Analytics(以下GA)に送信する必要が出てきました。
gtag.js
でカスタムディメンションをGAに送信する方法が調べてもあまり出てこなかったので、自分が行なった方法を公開することにしました。
前提条件
- WebSiteにGAやGTMを未実装
- GAのプロパティー作成済み(トラッキングコード取得済み)
- GTMのコンテナ作成済み(トラッキングコード取得済み)
ざっくりな構成図
簡単に以下に流れをまとめます。
下準備
- WebSiteにGTMのトラッキングコードを実装する
- GAでカスタムディメンションを作成する
実装の流れ
- GTMにてトリガーを作成する(発火タイミングの調整)
-
gtag.js
のコードを修正・追加してカスタムディメンションを送れるようにする - GTMにてタグを作成する(
gtag.js
を登録) - GTMのプレビューモードにて、タグが発火しているかどうかを確認しながら、GAの
リアルタイム
でデータが送れていることを確認する
それでは、詳細を説明していきます。
下準備
WebSiteにGTMのトラッキングコードを実装する
まずは、GTMのトラッキングコードをWebSiteに実装します。
<head>
内のなるべく上に以下のコードを貼り付けます。
以下は参考コードです。
<!-- 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-xxxxxxx');</script>
<!-- End Google Tag Manager -->
<body>
直後の以下のコードを貼り付けます。
以下は参考コードです。
<!-- Google Tag Manager (noscript) -->
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-xxxxxxx"
height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
<!-- End Google Tag Manager (noscript) -->
GAでカスタムディメンションを作成する
GAでカスタムディメンションを作成しておきます。
管理ページ
にアクセスします。
必要なだけ、カスタムディメンションを作成します。
例えば、Google Analytics Standard版のトラッキングデータをBigQueryにためてLookerで分析をしたい 01では、以下のようになります。
# | カスタムディメンション名 | 範囲 |
---|---|---|
1 | hitId | ヒット |
3 | clientId | ユーザー |
4 | datetime | ヒット |
5 | sessionNumber | ヒット |
6 | order_id | ヒット |
インデックスNoは後ほど実装で使うので番号を控えておきます。
実装
いよいよ実装に入ります。
GTMのプレビューモードで動作を確認しながら実装していくことになると思います。
GTMにてトリガーを作成する
まずはトリガーの作成です。
GTMでは、タグの発火タイミングをトリガー
と表現しています。
要するに発火タイミングを作成するということです。
SPAがどう実装されているかにもよりますが、今回はページリンクが押下された際にイベントが発火するようにトリガーを作成します。
以下のパターンを作成します。
click navi button
- トリガーのタイプ : クリック - リンクのみ
- トリガーの発生場所 : 一部のリンククリック
- イベント発生条件 :
Click Classes
正規表現に一致
navi-item|action-button|etc…
要素をクリックされた際に発火するトリガーです。
設定イメージは以下の通り。
after submit and view element
- トリガーのタイプ : 要素の表示
- 選択方法 : CSSセレクタ
- 要素セレクタ : div.email-thanks
- このトリガーを起動するタイミング : 各要素が画面に表示されるたび
- DOMの変化をモニタリング
- このトリガーの発生場所 : すべての表示イベント
SPAのために、submit
時にページ遷移がありません。
そのために、submit
後に表示されるお問い合わせありがとうござました
等の要素が表示された際に発火するトリガーとして設定しています。
設定イメージは以下の通り。
gtag.js
のコードを修正・追加してカスタムディメンションを送れるようにする
上記でトリガーを作成したら、いよいよタグを作っていきます。
タグはカスタムHTML
を利用し、コードをカスタムしたものを登録していきます。
実現したいこと
- ページタイトルとページパスを都度、取得する
- ページタイトルとページパスは
#
以降が単なる数字の場合があるので、コード内で書き換えることで対処する -
desktop & tablet
とmobile
で判別をする
- ページタイトルとページパスは
- お問い合わせ送信時のイベントはサブドメインごとに判別できるようにする
- 処理順をCookieを利用して取得する
- サブドメインを横断するように実装する
コード例
<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-xxxxxxxx-x"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
// get page path title
newPagePath = '';
newPageTitle = '';
getPagePathTitle();
eventLabel = 'submit_' + subDomainName;
// get hitid
hitId = '';
datetime = '';
getHitId();
// set sequence_number
setSequenceNumber();
document.cookie = cookie_sequence_number;
gtag('config', 'UA-xxxxxxxx-x', {
'custom_map': {
'dimension2': 'clientId',
'dimension3': 'hitId',
'dimension4': 'datetime',
'dimension5': 'sequenceNumber'
},
'page_title': newPageTitle,
'page_path': newPagePath,
'hitId': hitId,
'datetime': datetime,
'sequenceNumber': sequence_number
});
gtag('event', 'click', {
'event_category': 'form',
'event_label': eventLabel,
'value': 1
});
function getPagePathTitle(){
// UA判定処理
ua = '';
checkUa = navigator.userAgent;
if (checkUa.indexOf('iPhone') > 0 || checkUa.indexOf('Android') > 0 && checkUa.indexOf('Mobile') > 0) {
ua = 'mobile';
} else if (checkUa.indexOf('iPad') > 0 || checkUa.indexOf('Android') > 0) {
ua = 'tablet';
} else {
ua = 'desktop';
}
// pathとtitleを設定
pageTitle = document.title;
newPagePath = location.pathname + location.hash;
// www looker 判別
subDomainName = location.hostname.replace(/(.*)\.fbpp\.jp/g,'$1');
// pathとtitleを書き換え
if(subDomainName === 'www'){
if(ua === 'desktop' || ua === 'tablet'){
if(location.hash){
var pageTitleHash = location.hash.replace(/^#/g,'');
if(pageTitleHash === '1'){
pageTitleHash = 'top';
newPagePath = '/#' + pageTitleHash;
newPageTitle = pageTitleHash + ' | ' + pageTitle;
}else if(pageTitleHash === '2'){
pageTitleHash = 'our-services'
newPagePath = '/#' + pageTitleHash;
newPageTitle = pageTitleHash + ' | ' + pageTitle;
}else{
newPageTitle = pageTitleHash + ' | ' + pageTitle;
}
}else{
newPageTitle = pageTitle;
}
}else{
if(location.hash){
var pageTitleHash = location.hash.replace(/^#/g,'');
switch (pageTitleHash) {
case '1':
pageTitleHash = 'top';
newPagePath = '/#' + pageTitleHash;
break;
case '2':
pageTitleHash = 'our-services'
newPagePath = '/#' + pageTitleHash;
break;
case '3':
pageTitleHash = 'who-we-are'
newPagePath = '/#' + pageTitleHash;
break;
case '4':
pageTitleHash = 'about'
newPagePath = '/#' + pageTitleHash;
break;
case '5':
pageTitleHash = 'news'
newPagePath = '/#' + pageTitleHash;
break;
case '6':
pageTitleHash = 'careers'
newPagePath = '/#' + pageTitleHash;
break;
case '8':
pageTitleHash = 'contact-us'
newPagePath = '/#' + pageTitleHash;
break;
}
newPageTitle = pageTitleHash + ' | ' + pageTitle;
}else{
newPageTitle = pageTitle;
}
}
}else if(subDomainName === 'looker'){
if(ua === 'desktop' || ua === 'tablet'){
if(location.hash){
var pageTitleHash = location.hash.replace(/^#/g,'');
newPageTitle = pageTitleHash + ' | ' + pageTitle;
}else{
newPageTitle = pageTitle;
}
}else{
if(location.hash){
var pageTitleHash = location.hash.replace(/^#/g,'');
switch (pageTitleHash) {
case '1':
pageTitleHash = 'top';
newPagePath = '/#' + pageTitleHash;
break;
case '2':
pageTitleHash = 'news'
newPagePath = '/#' + pageTitleHash;
break;
case '4':
pageTitleHash = 'points'
newPagePath = '/#' + pageTitleHash;
break;
case '5':
pageTitleHash = 'partners'
newPagePath = '/#' + pageTitleHash;
break;
case '6':
pageTitleHash = 'innovation'
newPagePath = '/#' + pageTitleHash;
break;
case '7':
pageTitleHash = 'case-study'
newPagePath = '/#' + pageTitleHash;
break;
case '9':
pageTitleHash = 'installation'
newPagePath = '/#' + pageTitleHash;
break;
case '10':
pageTitleHash = 'about-us'
newPagePath = '/#' + pageTitleHash;
break;
case '11':
pageTitleHash = 'contact'
newPagePath = '/#' + pageTitleHash;
break;
}
newPageTitle = pageTitleHash + ' | ' + pageTitle;
}else{
newPageTitle = pageTitle;
}
}
}else if(subDomainName === 'fivetran'){
if(ua === 'desktop' || ua === 'tablet'){
if(location.hash){
var pageTitleHash = location.hash.replace(/^#/g,'');
if(pageTitleHash === '2'){
pageTitleHash = 'points';
newPagePath = '/#' + pageTitleHash;
newPageTitle = pageTitleHash + ' | ' + pageTitle;
}else{
newPageTitle = pageTitleHash + ' | ' + pageTitle;
}
}else{
newPageTitle = pageTitle;
}
}else{
if(location.hash){
var pageTitleHash = location.hash.replace(/^#/g,'');
switch (pageTitleHash) {
case '1':
pageTitleHash = 'top';
newPagePath = '/#' + pageTitleHash;
break;
case '2':
pageTitleHash = 'points'
newPagePath = '/#' + pageTitleHash;
break;
case '4':
pageTitleHash = 'feature'
newPagePath = '/#' + pageTitleHash;
break;
case '5':
pageTitleHash = 'connectors'
newPagePath = '/#' + pageTitleHash;
break;
case '6':
pageTitleHash = 'bi'
newPagePath = '/#' + pageTitleHash;
break;
case '7':
pageTitleHash = 'case-study'
newPagePath = '/#' + pageTitleHash;
break;
case '8':
pageTitleHash = 'installation'
newPagePath = '/#' + pageTitleHash;
break;
case '9':
pageTitleHash = 'about-us'
newPagePath = '/#' + pageTitleHash;
break;
case '10':
pageTitleHash = 'contact'
newPagePath = '/#' + pageTitleHash;
break;
}
newPageTitle = pageTitleHash + ' | ' + pageTitle;
}else{
newPageTitle = pageTitle;
}
}
}
}
function getHitId(){
// グローバル変数定義
hitId = '';
datetime = '';
// clientIdを取得する
var getc = '';
var arck = document.cookie.split(';');
arck.forEach(function(value){
var content = value.split('=');
if(content[0].trim() == '_ga'){
getc = content[1].replace(/(^GA[0-9]+\.2\.)(.*)/g,'$2');
return getc;
}
})
// 日時を取得
var date = new Date();
// datetimeを設定
var set_year = date.getFullYear();
var set_month = date.getMonth()+1;
var set_day = date.getDate();
var set_hours = date.getHours();
var set_minutes = date.getMinutes();
var set_seconds = date.getSeconds();
datetime = set_year + '-' + set_month + '-' + set_day + ' ' + set_hours + ':' + set_minutes + ':' + set_seconds;
// timestampを設定
var timestamp = date.getTime();
// hitIdを設定
hitId = timestamp + '_' + getc;
}
function setSequenceNumber(){
var cookie_domain = 'fbpp.jp';
var cookie_max_age = 60 * 30; // 30分
var cookie_path = '/';
var regex = new RegExp(/sequence_number/);
var cookie_raw = document.cookie;
if(regex.test(cookie_raw)){
var arsq = cookie_raw.split(';');
arsq.forEach(function(value){
var content = value.split('=');
if(content[0].trim() == 'sequence_number'){
sequence_number = Number(content[1]) + 1;
return sequence_number;
}
})
}else{
sequence_number = 1;
}
cookie_sequence_number = 'sequence_number=' + sequence_number + ';domain=' + cookie_domain + ';max-age=' + cookie_max_age + ';path=' + cookie_path;
cookie_sequence_data = new Object();
cookie_sequence_data.sequence_number = sequence_number;
cookie_sequence_data.cookie_sequence_number = cookie_sequence_number;
return cookie_sequence_data;
}
</script>
参考までに、標準のgtag.js
は以下になります。
とてもシンプルですね。
<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-xxxxxxxx-x"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'UA-xxxxxxxx-x');
</script>
カスタムディメンションを送信する際の注意点
カスタムディメンションを送信する際は、まずcustom_map
でマッピングをする必要があります。
以下の'custome_map': {}
の箇所になります。
マッピング後、それぞれ設定した例えば'hitId': hitId
などで値をGAに送信しています。
詳細の説明は本家の情報を参照してみてください。
gtag('config', 'UA-xxxxxxxx-x', {
'custom_map': {
'dimension2': 'clientId',
'dimension3': 'hitId',
'dimension4': 'datetime',
'dimension5': 'sequenceNumber'
},
'page_title': newPageTitle,
'page_path': newPagePath,
'hitId': hitId,
'datetime': datetime,
'sequenceNumber': sequence_number
});
イベントを送信する際の注意点
イベントを送信する際は、以下で行なっています。
event_category
やevent_label
は何を設定するのかは自由ですので、自身の運用方針に合わせて設定してください。
こちらについての詳細については本家の情報を参照してみてください。
gtag('event', 'click', {
'event_category': 'form',
'event_label': eventLabel,
'value': 1
});
GTMにてタグを作成する
上記で作成したコードをタグ
に登録していきます。
GA Click Navi
- タグの種類 : カスタムHTML
- タグの優先度 : 10(最初に呼び出したいので大きめの数字を入れています)
- タグの呼び出しオプション : 1回のイベントにつき1度
- トリガー :
click navi button
after submit and view element
- トリガーについては、
click navi button
とafter submit and view element
ではGAコードに内容に違いがありますが、説明簡略化のため、一つにしています -
after submit and view element
トリガーでは、submit
イベントが必要 -
click navi button
トリガーでは、submit
イベントが不要
- トリガーについては、
参考までに以下がGTMの設定画面です。
GTMのプレビューモードにて、タグが発火しているかどうかを確認しながら、GAのリアルタイム
でデータが送れていることを確認する
GTMのプレビューモードを使って、タグの発火状況を確認します。
プレビューモードを有効にする
WebSiteでタグの発火状況を確認する
WebSiteにアクセスし、タグの発火状況を確認する。
まとめ
以上が、Google Analyticsのgtag.js(カスタムディメンション)とGoogleタグマネージャーで、SPA(Single Page Application)のWebSiteをトラッキングできるようのする
方法です。
参考になればと思います。