Analytics

Track user behavior with Umami and Vercel Analytics

The template includes two privacy-friendly analytics integrations: Umami (self-hosted or cloud) and Vercel Analytics. Both are GDPR compliant, cookie-free, and load automatically when configured.

What's included

Two client plugins:

  • app/plugins/umami.client.ts - Umami integration
  • app/plugins/vercel-analytics.client.ts - Vercel Analytics integration

One unified composable:

  • app/composables/useAnalytics.ts - safe track() that fans out to all enabled providers

Features:

  • Privacy-focused (GDPR compliant, no cookies)
  • Conditional loading (only loads when env vars are set)
  • Automatic page view tracking
  • Can use one or both simultaneously
  • Unified custom event API — one call reaches every enabled provider

Umami Analytics

Quick setup

  1. Create an Umami account:
  2. Configure environment variables:
.env
NUXT_PUBLIC_UMAMI_ID="your-website-id"
NUXT_PUBLIC_UMAMI_HOST="https://cloud.umami.is"

For self-hosted: use your own domain (e.g., https://analytics.yourdomain.com)

Both variables are required. If either is missing, Umami won't load.

That's it! The plugin automatically injects the tracking script and tracks page views.

Vercel Analytics

Quick setup

  1. Enable in Vercel dashboard:
    • Go to your project at vercel.com
    • Settings → Analytics → Enable Web Analytics
  2. Configure environment variable:
.env
NUXT_PUBLIC_VERCEL_ANALYTICS="true"
Works on any hosting platform, not just Vercel. Data is sent to Vercel's analytics service.

Using both providers

Enable both for comprehensive tracking:

.env
NUXT_PUBLIC_UMAMI_ID="your-website-id"
NUXT_PUBLIC_UMAMI_HOST="https://cloud.umami.is"
NUXT_PUBLIC_VERCEL_ANALYTICS="true"

Why use both?

  • Umami: Full control, self-hosting option, privacy compliance
  • Vercel Analytics: Web Vitals, performance metrics, built-in with Vercel deployments

Environment-specific setup

Development: Omit variables to disable tracking during local development

Production: Set all desired analytics variables in your hosting platform's environment settings

Custom event tracking

Use the useAnalytics() composable to track custom events. It fans out to all enabled providers in a single call, so you don't need to know (or care) which ones are configured at any given time.

<script setup lang="ts">
const { track } = useAnalytics()

const handlePurchase = () => {
  track('purchase', { plan: 'pro', amount: 29 })
}
</script>

<template>
  <Button @click="handlePurchase">Buy Now</Button>
</template>

The composable lives at app/composables/useAnalytics.ts and is auto-imported by Nuxt — no manual import needed.

Why a composable instead of calling providers directly?

Calling umami.track(...) directly is unsafe: if the Umami script hasn't loaded (network failure, adblocker, missing config), referencing the bare umami identifier throws a ReferenceError that kills the surrounding handler. Optional chaining (umami?.track(...)) does not save you — it only short-circuits null/undefined values, not undeclared identifiers.

The composable handles all the safety concerns for you:

  • Optional chaining on window.umami — safe property access on an existing object (window).
  • Per-provider try/catch — a failure in one provider never affects the other or the surrounding UX.
  • import.meta.client guard — no-op on the server, so it's safe to call from anywhere.
  • Dev-only error logging — silent in production to keep the console clean.
Always go through useAnalytics(). Never reference a bare umami identifier or call window.umami.track() directly without the optional chain.

Privacy & compliance

GDPR compliant:

  • No cookies required
  • No personal data collection
  • IP addresses anonymized
  • Do Not Track (DNT) respected by Umami

Since these analytics are privacy-friendly, cookie consent banners typically aren't required. Check your local regulations.

Disabling in development

Both plugins automatically skip loading when environment variables aren't set. To disable analytics during local development, simply omit the variables from your .env file.

Troubleshooting

Scripts not loading:

  • Verify environment variables are set correctly
  • Check browser console for errors
  • Check Network tab for script requests

Data not appearing:

  • Wait a few minutes for data to process
  • Verify website ID/configuration in dashboard
  • Check that the script is loading (Network tab)

Reference

Start with Umami Cloud for the easiest setup. Self-host later if you need full control over your data.