Vue Analytics: Setup Guide for Vue 3 and Vue Router
Add cookieless analytics to a Vue 3 app: router-aware pageviews, custom events from components, and a setup that never touches your bundle size.
Vue apps with Vue Router are single-page applications, which means the classic analytics failure applies: one pageview per session, then silence. The fix used to be router afterEach hooks calling a tracking function — workable, but one more thing to forget. A tracker that instruments the History API directly makes the Vue setup a single script tag.
Installation
Add the tag to index.html — outside the Vue app entirely, so it survives any refactor:
<!-- index.html -->
<head>
<script
defer
src="https://clycyo.com/tracker.js"
data-tracking-id="YOUR_TRACKING_ID"
></script>
</head>Vue Router navigations (history mode) are detected automatically via pushState instrumentation — each route change records a pageview with its own SPA transition timing. Hash-mode routing also works; popstate and hashchange are both observed.
Events from components
<script setup>
function onUpgrade() {
window.webanalytics?.track('upgrade_clicked', {
plan: 'pro',
location: 'navbar',
});
}
</script>
<template>
<button @click="onUpgrade">Upgrade</button>
</template>The optional chaining is deliberate: ad blockers exist, and UI must never depend on analytics. For app-wide helpers, wrap track() in a composable (useAnalytics()) so calls stay consistent and testable.
identify() on login
// After successful auth
window.webanalytics?.identify(user.email);
// Persist for server-side revenue webhooks:
await api.patch('/me', {
clycyo_visitor_id: window.webanalytics?.getVisitorId(),
});That second call is the bridge to webhook revenue attribution — two lines now, channel-attributed MRR later.
What you get without writing anything
- Pageviews for full loads and router navigations, with per-route load/transition timing.
- Web Vitals (LCP, CLS, INP) from real users — Vue apps' INP is worth watching, since hydration and heavy reactivity land on the main thread.
- JavaScript errors with the route they occurred on — including errors your errorHandler swallows into a toast.
- Clicks, referrers, UTM capture, device and country.
Nuxt note
If you are on Nuxt rather than plain Vue, the setup moves to nuxt.config app.head and gains SSR considerations — covered separately in the Nuxt guide. Either way, total setup is one tag plus the events you choose; the quickstart has every snippet, and the free tier covers most Vue projects outright.