ブログタイトルのGAはGoogle Analytics(以下GA)ではないですが、Google Tag Manager(以下GTM)でGAを読み込んでいる場合、独自イベントの送信がちょっと面倒です。
下記のようなVueプラグインもあるけど、Vue.jsの環境はVue CLI 3で、GTMのタグはindex.htmlに公式通りに入れているため、今回はスルーした。
www.npmjs.com
シンプルなVueプラグインを作る
とりあえずエラーイベントを送るように下記のような感じで作った。
category, action, labelはGAのイベントと合わせた。
gtm-datalayer.js
const gtmDataLayer = {
install: function (Vue, options) {
const dataLayer = window.dataLayer || []
Vue.prototype.$gtm = {
sendErrorEvent: function(category, action, label){
dataLayer.push({
event: 'error',
eventCategory: category || 'defaultCategory',
eventAction: action || 'defaultAction',
eventLabel: label || 'defaultLabel'
})
}
}
}
}
export default gtmDataLayer
基本的にGTMのタグはHTMLの上の方で先に読み込んでいるはずで、dataLayerがセットされていないことはないはずだけど念の為、dataLayerがなくてもエラーが起きない(何も起きない)ようにしている。クリティカルな場面では使わないはず。
main.jsでインストールする
import GtmDataLayer from './plugins/gtm-datalayer'
Vue.use(GtmDataLayer)
これでvueのscript内から
this.$gtm.sendErrorEvent('お好きなカテゴリ', 'お好きなアクション', 'お好きなラベル')
みたいな感じで使える。
GTMで変数追加
勝手に送った変数はそのままでは使えない
ユーザー定義変数に上記、eventCategory、eventAction、eventLabelを追加する
GTMでカスタムイベント追加
カスタムイベントを受け取るトリガーを追加する。
とりあえず「すべてのカスタムイベント」にしたけど、あとで分けるなら、追加した変数を指定すればよさそう。
GTMでGAイベントのタグを追加
上で作った変数とトリガーを使って作る。
あとは公開するだけ。
Vue.js側から送信
これで送る。
今回はヤギが渡したはがきを食べた場面で送るようにした
//省略
methods: {
sampleError: function(){
this.$gtm.sendErrorEvent('yagi', 'eat', `yagi ate postcard! ${this.eatCount}: ${this.content}`)
}
}
//省略
GAのリアルタイムイベントで確認
取れた。
イベント名を汎用的なものに変更(2018/11/16追記)
GTM側のGTMのトリガーのイベント名をerrorで作ってしまったけど、エラーに限らず汎用的に使えるのでappEventに変更し、エラーはCategoryを使うようにしてみた。
const EVENT_NAME = 'appEvent'
const gtmDataLayer = {
install: function (Vue, options) {
const dataLayer = window.dataLayer || []
Vue.prototype.$gtm = {
sendError: function(action, label){
dataLayer.push({
event: EVENT_NAME,
eventCategory: 'appError',
eventAction: action || 'defaultAction',
eventLabel: label || 'defaultLabel'
})
}
}
}
}
export default gtmDataLayer
これで、エラーを送るときはカテゴリはappErrorで固定、actionとlabelだけ指定すればよくなった。actionに要約、labelに詳細みたいな感じで書けるので使いやすそう。
this.$gtm.sendError('yagiEte', `yagi ate postcard! count:${app.eatCount}, message:${tmpContent}`)