How to Integrate Google Analytics with Nuxt 3 (with Cookie Consent)
Every time I need to set up Google Analytics for a Nuxt project, I forget how to do it. To help myself and others, I decided to do a quick write up of the solution that will hopefully help some people (including myself) for future projects.
This implementation includes a cookie consent banner that allows users to opt-in or opt-out of tracking. This is important to comply with GDPR and other privacy regulations.
Create Google Analytics Account
Before starting, make sure that you have a Google Analytics account set up. If you don't have one yet, you can create an account here. The process is straightforward - simply enter info about your website and follow the instructions.
When asked to create a data-stream, select Web as the platform and enter your website URL. You will receive a tracking ID that you will need to add to your Nuxt project.
Set up Google Tag Manager
First, we need to set up Google Tag Manager. If you haven't done this yet, keep reading. If you already have Google Tag Manager set up, you can skip this step.
Create Account and Container
Visit the Google Tag Manager website and create an account. You will need a Google account to do this.
To create your account, click on the "Create Account" button and follow the instructions. Enter your app details and select Web as the target platform.
After creating your account, you will be redirected to your dashboard. In the topbar of the dashboard, you will find your Container ID. It should look something like GTM-XXXXXXX
. Remember where to find this Container ID as you will need it later.
Create Tag
On the Google Tag Manager dashboard, click on the "New Tag" button to create a new tag.
In the "Tag Configuration" section, select Google Analytics -> Google Tag as the tag type. You will need to enter a Tag-ID.
You can find this ID in your Google Analytics account by navigating to Admin -> Property Settings -> Data collection and modification -> Data Streams. Click on the corresponding data stream, and copy the Measurement ID, then add it into the Tag-ID field in Google Tag Manager.
In the "Triggering" section, select Initialization - All Pages to make sure that the tag is triggered on every page.
Install Dependencies
First, we need to install the @gtm-support/vue-gtm
package. This package is a wrapper around Google Tag Manager and makes it easy to integrate with Vue.
npm i @gtm-support/vue-gtm
Next, we need to install js-cookie
to manage cookies in our Nuxt project.
npm i js-cookie
Configure Google Tag Manager for Nuxt
To configure Google Tag Manager for Nuxt, we need to create a plugin that initializes the Google Tag Manager script.
Create a new file in the plugins
directory of your Nuxt project. Name it vue-gtm.client.js
.
import { createGtm } from '@gtm-support/vue-gtm'
import Cookies from 'js-cookie'
export default defineNuxtPlugin((nuxtApp) => {
const runtimeConfig = useRuntimeConfig().public
const consentGiven = Cookies.get('userConsent') === 'granted'
const router = useRouter()
nuxtApp.vueApp.use(
createGtm({
id: runtimeConfig.gtm_id,
defer: false,
compatibility: false,
enabled: runtimeConfig.gtm_enabled && consentGiven,
debug: runtimeConfig.gtm_debug,
loadScript: true,
vueRouter: router,
trackOnNextTick: false,
}),
)
})
Note that we reference the gtm_id
, gtm_enabled
, and gtm_debug
properties from the runtime config. To set these properties, we need to add them to the nuxt.config.js
file.
export default defineNuxtConfig({
runtimeConfig: {
public: {
gtm_id: process.env.GTM_ID,
gtm_enabled: true,
gtm_debug: process.env.ENVIRONMENT === 'development' ? true : false,
},
},
})
In the nuxt.config.js
file, we set the gtm_id
to the Google Tag Manager Container ID (GTM-XXXXXXX) and the gtm_debug
property to true
if the environment is set to development.
In our plugin, we check if the user has given consent by checking the userConsent
cookie. If the cookie is set to granted
, we enable Google Tag Manager. If the cookie is not set or set to denied
, Google Tag Manager is disabled.
To set the userConsent
cookie, we need to create a cookie consent banner.
Create Cookie Consent Banner
To create a cookie consent banner, we need to create a new component. Create a new file in the components
directory of your Nuxt project. Name it CookieConsent.vue
.
I'm using Tailwind CSS for styling, but you can use any CSS framework or custom styles.
<template>
<div
v-if="showBanner"
class="max-w-screen fixed bottom-0 w-full bg-black p-6"
>
<div
class="flex flex-col justify-between gap-6 text-white lg:mx-auto lg:max-w-7xl lg:flex-row lg:items-center"
>
<div>
<p class="font-display font-semibold">Cookies</p>
<p class="text-sm">
We use cookies to improve your experience. Do you accept?
</p>
</div>
<div class="flex gap-4">
<button
class="flex-grow rounded bg-gray-800 px-3 py-2 text-gray-200 lg:flex-grow-0"
@click="declineCookies"
>
Decline
</button>
<button
class="flex-grow rounded bg-blue-600 px-3 py-2 font-semibold text-white lg:flex-grow-0"
@click="acceptCookies"
>
Accept
</button>
</div>
</div>
</div>
</template>
<script setup>
import { ref, onMounted } from 'vue'
import Cookies from 'js-cookie'
import { useGtm } from '@gtm-support/vue-gtm'
const gtm = useGtm()
const showBanner = ref(false)
const acceptCookies = () => {
Cookies.set('userConsent', 'granted', { expires: 365 })
gtm.enable(true)
showBanner.value = false
}
const declineCookies = () => {
Cookies.set('userConsent', 'denied', { expires: 365 })
gtm.enable(false)
showBanner.value = false
}
onMounted(() => {
const consentStatus = Cookies.get('userConsent')
if (consentStatus === 'granted') {
gtm.enable(true)
showBanner.value = false
} else if (consentStatus === 'denied') {
showBanner.value = false
gtm.enable(false)
} else {
showBanner.value = true
}
})
</script>
In the CookieConsent.vue
component, we check if the userConsent
cookie is set. If the cookie is set to granted
, we enable Google Tag Manager and hide the banner. If the cookie is set to denied
, we hide the banner and disable Google Tag Manager. If the cookie is not set, we show the banner.
To make the CookieConsent component available on every page, we need to add it to the layout component. If you don't have a layout component yet, you can create one in the layouts
directory of your Nuxt project.
<!-- layouts/default.vue -->
<template>
<!-- Other components (header, etc.) -->
<slot />
<CookieBanner />
</template>
Now, the CookieConsent banner will be displayed on every page of your Nuxt project. Users can opt-in or opt-out of tracking by clicking the "Accept" or "Decline" button.
To test the implementation, run your Nuxt projects and open the developer tools. Select the "Elements" tab and confirm that the Google Tag Manager script is loaded when the user accepts cookies. You can also check the cookies in the "Application" tab to see if the userConsent
cookie is set.
Next Steps
That's it, you have successfully integrated Google Analytics with Nuxt 3 and added a cookie consent banner to comply with privacy regulations.
I hope this tutorial was useful for you. If you have any questions, feel free to reach out to me at pk@pkundr.com.
I also offer services in the areas of Product Management and Web development. If you need help with a project, I would be happy to discuss it with you.
Philipp