Analytics

Track user behavior with Umami and Vercel Analytics

This boilerplate supports privacy-friendly analytics through Umami (self-hosted or cloud) and Vercel Analytics to help you understand how users interact with your application.

Overview

The analytics system provides:

  • Privacy-focused - GDPR compliant, no cookies required
  • Conditional loading - Only loads when configured
  • Multiple providers - Use Umami, Vercel Analytics, or both
  • Automatic page tracking - No manual instrumentation needed
  • Real-time data - Monitor traffic as it happens
  • Server-side - Environment-based configuration

Umami Analytics

Umami is a privacy-focused, open-source analytics platform that you can self-host or use via their cloud service.

Setup

  1. Create account:
    • Go to Umami Cloud
    • Sign up for a free or paid account
    • Create a new website
  2. Get tracking information:
    • Copy your website ID from the dashboard
    • Note your tracking script URL (usually https://cloud.umami.is)

Option 2: Self-hosted

  1. Deploy Umami:
  2. Get tracking information:
    • Copy your website ID
    • Note your instance URL (e.g., https://analytics.yourdomain.com)

Configuration

Add your Umami credentials to .env:

.env
# Umami Analytics
NUXT_PUBLIC_UMAMI_ID="your-website-id"
NUXT_PUBLIC_UMAMI_HOST="https://cloud.umami.is"

For self-hosted instances, use your own domain:

.env
NUXT_PUBLIC_UMAMI_HOST="https://analytics.yourdomain.com"
Both variables are required. If either is missing, Umami tracking won't load.

How it works

The Umami plugin (app/plugins/umami.client.ts) automatically:

  1. Checks if NUXT_PUBLIC_UMAMI_ID and NUXT_PUBLIC_UMAMI_HOST are set
  2. Injects the Umami tracking script into the page
  3. Tracks page views automatically
  4. Respects Do Not Track (DNT) headers

No additional configuration is needed - just set the environment variables and deploy!

Viewing analytics

  1. Log into your Umami dashboard
  2. Select your website
  3. View real-time and historical data:
    • Page views and unique visitors
    • Traffic sources and referrers
    • Device, browser, and OS statistics
    • Geographic location data
    • Custom events (if implemented)

Vercel Analytics

Vercel Analytics provides real-time traffic insights for applications deployed on Vercel.

Setup

  1. Enable in Vercel dashboard:
    • Go to your project on vercel.com
    • Navigate to Settings → Analytics
    • Enable Web Analytics
    • No additional configuration needed on Vercel side
  2. Enable in your application:

Add to .env:

.env
# Vercel Analytics (set to any truthy value to enable)
NUXT_PUBLIC_VERCEL_ANALYTICS="true"
Vercel Analytics works on any hosting platform, not just Vercel. The tracking data is sent to Vercel's analytics service.

How it works

The Vercel Analytics plugin (app/plugins/vercel-analytics.client.ts) automatically:

  1. Checks if NUXT_PUBLIC_VERCEL_ANALYTICS is set
  2. Injects the Vercel Analytics script using the official @vercel/analytics package
  3. Tracks page views and Web Vitals automatically
  4. Sends data to Vercel's analytics dashboard

Viewing analytics

  1. Go to your project on vercel.com
  2. Click the "Analytics" tab
  3. View metrics including:
    • Real-time visitor count
    • Page views and unique visitors
    • Top pages and referrers
    • Geographic distribution
    • Web Vitals (performance metrics)

Using both providers

You can use both Umami and Vercel Analytics simultaneously:

.env
# Use both analytics providers
NUXT_PUBLIC_UMAMI_ID="your-website-id"
NUXT_PUBLIC_UMAMI_HOST="https://cloud.umami.is"
NUXT_PUBLIC_VERCEL_ANALYTICS="true"

This gives you:

  • Umami for full control and privacy compliance
  • Vercel Analytics for Web Vitals and performance insights

Environment-specific configuration

Development

Omit analytics variables to disable tracking during development:

.env
# No analytics variables - tracking disabled

Or use a separate Umami website for development tracking:

.env
NUXT_PUBLIC_UMAMI_ID="dev-website-id"
NUXT_PUBLIC_UMAMI_HOST="https://cloud.umami.is"

Staging

Use the same credentials as production or create separate tracking:

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

Production

Enable all desired analytics:

.env.production
NUXT_PUBLIC_UMAMI_ID="production-website-id"
NUXT_PUBLIC_UMAMI_HOST="https://analytics.yourdomain.com"
NUXT_PUBLIC_VERCEL_ANALYTICS="true"

Testing analytics

Verify script loading

  1. Open browser DevTools (F12)
  2. Check Network tab:
    • Look for requests to your Umami host
    • Look for requests to /_vercel/insights/
  3. Check Console for any errors

Test page tracking

  1. Navigate between pages in your application
  2. Check your analytics dashboard
  3. Verify page views are being recorded
Use browser incognito/private mode to test tracking without interfering with your own analytics data.

Debug mode

For Umami, you can enable debug logging by adding to the script tag (manually in the plugin):

app/plugins/umami.client.ts
useHead({
  script: [
    {
      src: `${umamiHost}/script.js`,
      async: true,
      defer: true,
      'data-website-id': umamiId,
      'data-do-not-track': 'false', // For testing, disable DNT
      'data-domains': 'yourdomain.com', // Optional: only track on specific domains
    },
  ],
})

Custom event tracking

Umami custom events

Track custom events using the Umami global:

<script setup>
const trackDownload = () => {
  // @ts-ignore - Umami global
  if (window.umami) {
    window.umami.track('download', { file: 'whitepaper.pdf' })
  }
}
</script>

<template>
  <button @click="trackDownload">Download Whitepaper</button>
</template>

Vercel Analytics custom events

Track custom events using the Vercel Analytics package:

<script setup>
import { track } from '@vercel/analytics'

const trackSignup = () => {
  track('signup', { plan: 'pro' })
}
</script>

<template>
  <button @click="trackSignup">Sign Up</button>
</template>

Privacy compliance

GDPR

Both Umami and Vercel Analytics are GDPR compliant:

  • No cookies - Analytics work without cookies
  • No personal data - Only aggregated, anonymous data
  • IP anonymization - IP addresses are not stored
  • User consent - Not required for privacy-friendly analytics

Do Not Track

Umami respects the "Do Not Track" browser setting by default. Users with DNT enabled won't be tracked.

Since these analytics don't use cookies and don't track personal data, you typically don't need cookie consent banners. However, check your local regulations.

Always review your specific legal requirements. This is not legal advice.

Advanced configuration

Filter out localhost

Umami automatically ignores localhost traffic. For Vercel Analytics, you can add conditional logic:

app/plugins/vercel-analytics.client.ts
import { inject } from '@vercel/analytics'

export default defineNuxtPlugin(() => {
  const config = useRuntimeConfig()

  // Only load on production domains
  if (config.public.vercelAnalytics && !window.location.hostname.includes('localhost')) {
    inject()
  }
})

Custom domains

For self-hosted Umami, you can use a custom domain:

.env
NUXT_PUBLIC_UMAMI_HOST="https://analytics.yourdomain.com"

Make sure to:

  1. Point your DNS to your Umami instance
  2. Configure SSL certificate
  3. Update CORS settings if needed

Proxy Umami script

To prevent ad blockers from blocking analytics, proxy the Umami script through your own domain:

  1. Add a Nitro route rule in nuxt.config.ts:
nuxt.config.ts
export default defineNuxtConfig({
  nitro: {
    routeRules: {
      '/analytics/script.js': {
        proxy: `${process.env.NUXT_PUBLIC_UMAMI_HOST}/script.js`,
      },
    },
  },
})
  1. Update the plugin to use your proxied URL:
app/plugins/umami.client.ts
useHead({
  script: [
    {
      src: '/analytics/script.js', // Use proxied path
      async: true,
      defer: true,
      'data-website-id': umamiId,
    },
  ],
})

Troubleshooting

Analytics not loading

Check environment variables:

# Verify variables are set
env | grep UMAMI
env | grep VERCEL

Check browser console for errors.

Verify script URLs in Network tab.

Ad blockers

Ad blockers may block analytics scripts. Solutions:

  1. Use proxy method (see Advanced Configuration)
  2. Use custom domain for Umami
  3. Accept that some users block analytics - it's their choice

Data not appearing

For Umami:

  • Verify website ID is correct
  • Check Umami dashboard for website status
  • Ensure Umami instance is accessible
  • Check CORS settings on self-hosted instances

For Vercel Analytics:

  • Ensure Analytics is enabled in Vercel dashboard
  • Wait a few minutes for data to appear
  • Check that deployment is successful

Development tracking

To disable analytics in development:

app/plugins/umami.client.ts
export default defineNuxtPlugin(() => {
  const config = useRuntimeConfig()

  // Disable in development
  if (process.env.NODE_ENV === 'development') {
    return
  }

  // ... rest of the plugin
})

Migration from other platforms

From Google Analytics

Umami provides a cleaner, privacy-focused alternative:

  1. Set up Umami as described above
  2. Keep GA running in parallel initially
  3. Compare data for accuracy
  4. Remove GA once comfortable with Umami

From other platforms

Most analytics platforms track similar metrics. The transition is straightforward:

  1. Set up new analytics
  2. Run both platforms in parallel
  3. Update any custom event tracking
  4. Remove old analytics when ready

Performance impact

Both analytics solutions are designed for minimal performance impact:

  • Umami: ~3KB gzipped, async loading
  • Vercel Analytics: ~1KB gzipped, async loading
  • Combined: ~4KB total, negligible impact

Scripts load asynchronously and don't block page rendering.

Reference

Start with one analytics provider and add the second later if needed. Umami is recommended for full control and privacy compliance.