Clycyo
Frameworks5 min read

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.