I'm trying to build a Google Analytics plugin to Nuxt that will fetch tracking IDs from the CMS. I am really close I think.
I have a plugin file loading on client side only. The plugin is loaded from nuxt.config.js via the plugins:[{ src: '~/plugins/google-gtag.js', mode: 'client' }] array.
From there the main problem is that the gtag script needs the UA code in it's URL, so I can't just add that into the regular script object in nuxt.config.js. I need to get those UA codes from the store (which is hydrated form nuxtServerInit.
So I'm using head.script.push in the plugin to add the gtag script with the UA code in the URL. But that doesn't result in the script being added on first page load, but it does for all subsequent page transitions. So clearly I'm running head.script.push too late in the render of the page.
But I don't know how else to fetch tracking IDs, then add script's to the head.
// plugins/google.gtag.client.js with "mode": "client
export default ({ store, app: { head, router, context } }, inject) => {
// Remove any empty tracking codes
const codes = store.state.siteMeta.gaTrackingCodes.filter(Boolean)
// Add script tag to head
head.script.push({
src: `https://www.googletagmanager.com/gtag/js?id=${codes[0]}`,
async: true
})
console.log('added script')
// Include Google gtag code and inject it (so this.$gtag works in pages/components)
window.dataLayer = window.dataLayer || []
function gtag() {
dataLayer.push(arguments)
}
inject('gtag', gtag)
gtag('js', new Date())
// Add tracking codes from Vuex store
codes.forEach(code => {
gtag('config', code, {
send_page_view: false // necessary to avoid duplicated page track on first page load
})
console.log('installed code', code)
// After each router transition, log page event to Google for each code
router.afterEach(to => {
gtag('event', 'page_view', { page_path: to.fullPath })
console.log('afterEach', code)
})
})
}