Frameworks · 2 min setup
How to add analytics to Nuxt
app.head.script in nuxt.config.ts with defer: true and a data-site attribute. Nuxt renders it into every page's <head> on the server, and the script counts each client-side route change as a pageview.Updated
Nuxt manages the document head for you (through Unhead), so there's no index.html to edit. Declaring the script in nuxt.config.ts puts it in the server-rendered HTML of every route — including prerendered and statically generated ones — exactly once.
Nuxt at a glance
- Where the tag goes
app.head.scriptinnuxt.config.ts- Rendering
- In the SSR / prerendered HTML of every route
- Route changes
- Tracked automatically
- Works with
- Nuxt 3, Nuxt 4,
nuxi generate, Nitro on any host - Custom events
window.visitrack()in client code
How to install VisitTrack on Nuxt
Step 1: Copy your site id
Copy the snippet from the install step (or Settings → General) in VisitTrack. Replace
SITE_IDbelow with your id.Step 2: Add the script to nuxt.config.ts
Attribute names with a dash need quotes.
defer: truerenders a baredeferattribute.nuxt.config.tsexport default defineNuxtConfig({ app: { head: { script: [ { src: "https://visitrack.app/tracker.js", defer: true, "data-site": "SITE_ID", }, ], }, }, });Step 3: Optional: read the id from runtime config
If several environments share the code, keep the id in an environment variable and add the script from
app.vuewithuseHead. Leave the variable empty on staging and nothing is rendered there.app.vue<script setup lang="ts"> const { public: env } = useRuntimeConfig(); // runtimeConfig.public.visitrackSiteId useHead({ script: env.visitrackSiteId ? [{ src: "https://visitrack.app/tracker.js", defer: true, "data-site": env.visitrackSiteId }] : [], }); </script>Step 4: Deploy and open the site
nuxi devruns on localhost, which the tracker skips. Build and deploy (ornuxi generate), then browse the live site.
How to check VisitTrack is working on Nuxt
- View the page source of your deployed site: the
<head>contains the tracker tag with yourdata-site. - Click between two pages; the VisitTrack live view shows you, and the Pages tab lists both paths.
- DevTools → Network shows a
POSTtovisitrack.app/api/collecton each navigation.
Does VisitTrack track Nuxt page navigation?
Nuxt's router (Vue Router under the hood) navigates with history.pushState, which the tracker listens to — so <NuxtLink> and navigateTo() are counted as pageviews. Changing only query params isn't a new pageview, because pageviews are keyed on the pathname.
Because the head is managed per app (not per page), the same tag stays in place across navigations; Nuxt doesn't re-insert it, so there's no double counting.
How to track custom events and goals in Nuxt
Custom events run in the browser, so call them in client-side code — event handlers, onMounted, or a .client plugin. Guard with optional chaining: during SSR, window doesn't exist, and in the browser a blocker may have stopped the script.
<script setup lang="ts">
async function startTrial() {
const { ok } = await $fetch("/api/trial", { method: "POST" });
if (ok && import.meta.client) window.visitrack?.("trial_started", { plan: "pro" });
}
</script>
<template>
<NuxtLink to="/pricing" data-vt-goal="pricing_cta">Pricing</NuxtLink>
</template>Signups created in a Nitro server route can be sent from the server with POST /api/track and a secret API key — see server-side events.
Script options you might need on Nuxt
All optional — add them to the same tag. Full reference: script configuration.
| Attribute | What it does |
|---|---|
data-cookieless | Store nothing in the browser; the server derives a daily-rotating id. See cookieless mode. |
data-exclude="/app/*" | Never track these paths (comma-separated, * wildcard). Checked on every navigation. |
data-allow-local | Track on localhost and *.local — for testing an install only. |
data-debug | Log every event the script sends, and why it skipped one, to the console. |
data-auto="false" | Turn off automatic events (downloads, contact clicks, form submits, rage clicks, JS errors, 404s). |
Nuxt troubleshooting
window is not defined during SSR
A window.visitrack call ran on the server. Move it into an event handler, onMounted, or wrap it in if (import.meta.client).
The tag is missing from the HTML
Check that the script is under app.head (not a top-level head key) and that you restarted the dev server after editing nuxt.config.ts.
Blocked by Content-Security-Policy
If you use nuxt-security or your own headers, add https://visitrack.app to script-src and connect-src.
Staging traffic in production stats
Save your production hostnames under Settings → General → Allowed hostnames, or use the runtime-config variant above and leave the id empty on staging.
Nuxt analytics FAQ
Is there a Nuxt module for VisitTrack?
No; app.head.script is all it takes. A module would only wrap the same tag, and the config approach keeps the script in server-rendered HTML with no extra dependency.
Does VisitTrack work with Nuxt's static generation (nuxi generate)?
Yes. The tag is written into each generated HTML file, and client-side navigation between generated pages is tracked through the History API.
Can I use @nuxt/scripts' useScript instead?
You can, as long as the final <script> element carries data-site and loads once for the whole app. The tracker reads its configuration from its own script element. The nuxt.config.ts approach above is the simplest option that's guaranteed to do that.
How do I track signups in Nuxt?
Call window.visitrack("signup") in the browser after the signup request succeeds, or send the event from your server route with POST /api/track. See custom events.
Does Nuxt need a cookie banner with VisitTrack?
Not if you use cookieless mode, which stores nothing on the device. Add "data-cookieless": "" to the script object, or switch the whole site in Settings. General information, not legal advice.
Keep going
- Vue analyticsAdd VisitTrack to a Vue 3 app built with Vite by adding one tag to index.html — Vue Router history-mode navigations are tracked automatically.
- Next.js analyticsAdd VisitTrack to a Next.js App Router or Pages Router app with next/script — client-side route changes are tracked automatically.
- SvelteKit analyticsAdd VisitTrack to SvelteKit by adding one tag to src/app.html — client-side navigations are tracked, and kit.csp gets two extra sources.
- Netlify analyticsAdd VisitTrack on Netlify with Snippet injection (no code) or in your framework, keep deploy previews out, and set CSP in _headers.
- Install the tracking scriptThe reference tag, CSP notes and how to check it's working.
- Custom events and signupsvisitrack(), data-vt-goal, scroll events and server-side signups.
- Use casesHow SaaS teams, indie hackers, stores and agencies use VisitTrack.
- VisitTrack vs Google AnalyticsCookie-free analytics with revenue attribution, compared honestly.
Add VisitTrack to your Nuxt site
Cookie-free analytics with revenue attribution, live visitors, funnels and session replays. One script tag, every feature on every plan. 14 days free, no card required.
Not on Nuxt? See all 29 integration guides.