Integration guide
Analytics in Nuxt
A browser-only plugin creates the SDK, counts router navigations and exposes $analytics to components. Works with SSR, SSG and SPA mode.
Before you start
- Nuxt 3 (or 4).
- Your
site_key, and your domain under Allowed origins.
Installation
1Install the SDK and set the key
Nuxt fills
runtimeConfig.publicfromNUXT_PUBLIC_*environment variables.npm install @racoelho/analyticsnuxt.config.ts export default defineNuxtConfig({ runtimeConfig: { public: { analisaSiteKey: '', }, }, }).env NUXT_PUBLIC_ANALISA_SITE_KEY=YOUR_SITE_KEY2Create the plugin
The
.clientsuffix makes Nuxt load the plugin in the browser only — the SDK never runs on the server.plugins/analytics.client.ts import { Analytics } from '@racoelho/analytics' export default defineNuxtPlugin(() => { const config = useRuntimeConfig() // the .client suffix makes this run in the browser only const analytics = new Analytics({ siteKey: config.public.analisaSiteKey }) useRouter().afterEach((to, from) => { // only when the path changes; the first load is already counted if (to.path !== from.path) analytics.pageview() }) return { provide: { analytics } } })
Events and goals
In any component, get $analytics from useNuxtApp() and call track(name, properties).
<script setup lang="ts">
const { $analytics } = useNuxtApp()
function subscribe() {
$analytics.track('newsletter_signup', { place: 'footer' })
}
</script>
<template>
<button @click="subscribe">Subscribe</button>
</template>Create a newsletter_signup event goal in the dashboard. Since the plugin is client-only, use $analytics in event handlers or onMounted, never during server rendering.
Page navigation
After the first load Nuxt navigates without reloading, and the SDK does not notice that on its own — the plugin’s afterEach counts each new page. Query-string-only changes don’t count as a new page.
Check that it works
- Open the published site in a normal window, with no ad blocker.
- In your browser devtools, Network tab, filter by
v1/i: you should see aPOSTwith status200within 3 seconds (or when you leave the page). - In the dashboard, events show up in about 30 seconds.
- Navigate with a
<NuxtLink>and look for a newpage_viewin the nextPOST.
Troubleshooting
$analyticsisundefinedin a component- The code ran on the server, where the
.clientplugin doesn’t exist. Move the call into a click handler oronMounted. - The request returns 403 (
origin_not_allowed) - Your domain isn’t in Allowed origins in the site settings. Add the exact origin — with
https://, with and withoutwww, plus test addresses likehttp://localhost:3000if you want to measure in development. - No request shows up in the Network tab
- The SDK honors Do Not Track by default: if your browser sends DNT, nothing is sent. Test in another browser or profile. Ad blockers can also block the script.
- Pageviews show up twice
- The SDK was initialized twice (for example, pasted in the theme and also added by a plugin). Keep a single instance per page.
Create your account and grab the site_key
Free up to 10K events a month, no credit card.
Create a free account