one <script> + init · Vue Router autocaptured · open source (MIT)

Add analytics to Vue or Nuxt.
One script, one init.

Drop one <script src=.../sdk.js> in index.html and call smolanalytics.init. Vue Router navigations autocapture. Nuxt? add the same script via nuxt.config.ts app.head.script. No Vue plugin, no npm package.

nuxt.config.ts · add the script, then init in a client plugin
// nuxt.config.ts: load /sdk.js on every page
export default defineNuxtConfig({
  app: {
    head: {
      script: [
        { src: "https://your-instance/sdk.js", defer: true },
      ],
    },
  },
});

// plugins/smolanalytics.client.ts: init once
export default defineNuxtPlugin(() => {
  window.smolanalytics?.init({ site: "prj_live" });
});

// mark key moments from any component or composable
window.smolanalytics.identify(user.id);
window.smolanalytics.track("trial_started");

how do I add analytics to a Vue or Nuxt app?

To add analytics to a Vue app, drop one script tag into your index.html, <script src="https://YOUR_INSTANCE/sdk.js"></script>, then call smolanalytics.init with your site id. That single init gives you pageviews across your single-page app, because the smolanalytics (smolanalytics.com) SDK autocaptures Vue Router navigations, so soft route changes count as real pageviews, plus visitors, referrers, funnels, retention, and paths. For a Nuxt app you add the exact same script through nuxt.config.ts under app.head.script instead of index.html, and everything else is identical, there is no Vue plugin and no npm package to install, just the one script and one init. For key moments you call window.smolanalytics.track("signup_clicked") and window.smolanalytics.identify(userId) from any component or composable. Because identify keys off a stable distinct_id, a user's first pageview, their signup, and the server events you POST to /v1/events (payments, provisioning, webhooks) fuse into one funnel. It is an open-source single Go binary you self-host free forever, or a hosted instance from $9/month, and instead of building dashboards you ask it "where do users drop off?" in plain English and the answer is computed from your events, never guessed.

one script and one init, not a Vue plugin

One script tag, one init, no Vue plugin
Add <script src=".../sdk.js"> to index.html and call smolanalytics.init(siteId). That is the whole client install. It works the same in Vite + Vue, the Vue CLI, or any Vue setup, because it is a plain script and one call, not a plugin or an npm package you have to keep in sync.
Vue Router navigations autocaptured
The SDK hooks client-side navigation, so a soft route change under Vue Router counts as a real pageview, not one load at boot. You get pageviews, visitors, referrers, and paths across your whole single-page app from that one init, with no per-route wiring and no afterEach hook to maintain.
Nuxt: add the script in nuxt.config.ts
For Nuxt, put the same script under app.head.script in nuxt.config.ts so it loads on every page, then call smolanalytics.init in a client plugin. Same SDK, same events, same dashboard. Nuxt's route changes autocapture just like a plain Vue SPA, so nothing else changes.
track(), identify(), and one funnel
Call window.smolanalytics.track("trial_started") or window.smolanalytics.identify(userId) from any component or composable to mark the moments that matter. POST server events (Stripe webhooks, cron) to /v1/events with the same distinct_id, and a user's pageview, signup, and payment join into one funnel you can just ask about.

Honest pricing: 14-day full trial, no credit card. Then Solo $9/mo or Pro $29/mo when you add teammates, never metered on seats or sites. Overage is $5/million with an emailed receipt, the dashboard never locks, and self-hosting the single Go binary is free forever (MIT).

Add the script tonight.

One <script> plus one init for a Vue SPA, or the same script via nuxt.config.ts for Nuxt. Tomorrow morning the verdict tells you which part of the funnel to fix.

questions

How do I add analytics to a Vue app?
Drop one script tag into index.html: <script src="https://YOUR_INSTANCE/sdk.js"></script>, then call smolanalytics.init({ site: "YOUR_SITE_ID" }) once, for example in main.js after the app mounts. That gives you pageviews (including Vue Router navigations), visitors, referrers, funnels, retention, and paths from one init. There is no Vue plugin and no npm package to install. Mark key moments with window.smolanalytics.track() and window.smolanalytics.identify().
How do I add it to a Nuxt app?
Add the same script through nuxt.config.ts under app.head.script so it loads on every page: app: { head: { script: [{ src: "https://YOUR_INSTANCE/sdk.js", defer: true }] } }. Then call smolanalytics.init({ site: "YOUR_SITE_ID" }) in a client-side plugin (plugins/smolanalytics.client.ts). Nuxt route changes autocapture the same way a plain Vue SPA does, so nothing else changes.
Does it track single-page route changes?
Yes. The SDK hooks client-side navigation, so soft route changes under Vue Router (in a Vue SPA or in Nuxt) are counted as pageviews, not just the one hard load when the app boots. You do not wire anything per route or add a router.afterEach: init once and every navigation in the single-page app becomes a pageview automatically.
How do I track a button click or a signup?
Call window.smolanalytics.track("signup_clicked") from the handler, and window.smolanalytics.identify(userId) once you know who the user is. From a Vue component that is one line: <button @click="$smolanalytics?.track('upgrade_clicked')">Upgrade</button>, or reference window.smolanalytics in a method or composable. Those events flow straight into your funnels and paths.
How do client-side and server-side events end up as one user?
The same distinct_id. Call smolanalytics.identify(userId) in the browser and send that same value as distinct_id when you POST /v1/events from your server, and a user's Vue-side activity and their server events (payments, provisioning) join into one person's timeline and one funnel. Pick a stable id, your own user id works.
Is it enough for a real Vue or Nuxt product, or just page counts?
It does funnels, retention, paths, cohorts, channel-and-revenue attribution, and a daily verdict on what to fix, across client and server events. It deliberately does not do session replay, feature flags, heatmaps, or experiments, if you need those keep a tool like PostHog for them. It is for teams who want a straight answer on what to fix, that they own, cheap.
, then call smolanalytics.init({ site: \"YOUR_SITE_ID\" }) once, for example in main.js after the app mounts. That gives you pageviews (including Vue Router navigations), visitors, referrers, funnels, retention, and paths from one init. There is no Vue plugin and no npm package to install. Mark key moments with window.smolanalytics.track() and window.smolanalytics.identify()."}},{"@type":"Question","name":"How do I add it to a Nuxt app?","acceptedAnswer":{"@type":"Answer","text":"Add the same script through nuxt.config.ts under app.head.script so it loads on every page: app: { head: { script: [{ src: \"https://YOUR_INSTANCE/sdk.js\", defer: true }] } }. Then call smolanalytics.init({ site: \"YOUR_SITE_ID\" }) in a client-side plugin (plugins/smolanalytics.client.ts). Nuxt route changes autocapture the same way a plain Vue SPA does, so nothing else changes."}},{"@type":"Question","name":"Does it track single-page route changes?","acceptedAnswer":{"@type":"Answer","text":"Yes. The SDK hooks client-side navigation, so soft route changes under Vue Router (in a Vue SPA or in Nuxt) are counted as pageviews, not just the one hard load when the app boots. You do not wire anything per route or add a router.afterEach: init once and every navigation in the single-page app becomes a pageview automatically."}},{"@type":"Question","name":"How do I track a button click or a signup?","acceptedAnswer":{"@type":"Answer","text":"Call window.smolanalytics.track(\"signup_clicked\") from the handler, and window.smolanalytics.identify(userId) once you know who the user is. From a Vue component that is one line: , or reference window.smolanalytics in a method or composable. Those events flow straight into your funnels and paths."}},{"@type":"Question","name":"How do client-side and server-side events end up as one user?","acceptedAnswer":{"@type":"Answer","text":"The same distinct_id. Call smolanalytics.identify(userId) in the browser and send that same value as distinct_id when you POST /v1/events from your server, and a user's Vue-side activity and their server events (payments, provisioning) join into one person's timeline and one funnel. Pick a stable id, your own user id works."}},{"@type":"Question","name":"Is it enough for a real Vue or Nuxt product, or just page counts?","acceptedAnswer":{"@type":"Answer","text":"It does funnels, retention, paths, cohorts, channel-and-revenue attribution, and a daily verdict on what to fix, across client and server events. It deliberately does not do session replay, feature flags, heatmaps, or experiments, if you need those keep a tool like PostHog for them. It is for teams who want a straight answer on what to fix, that they own, cheap."}}]}

keep reading