vTilt
By roleFoundersKnow what to fix firstMarketersSee what happens after the clickCMOsSee what your budget really buys
By businessSaaSTurn signups into active usersEcommerceSee why shoppers abandon cartsAgenciesProve your work to clientsEnterpriseOne customer record for every team
MeasureWeb AnalyticsFind where buyers leaveSession ReplaySee why they left, not just that they didAdsKnow what paid visitors do nextIntegrationsOne snippet feeds your stack
ThinkPeopleOne profile per customerCustomer MemoryvTilt remembers every visitorSite KnowledgeAnswers and audits from your own pages
ActAsk AIAnswers from real behaviorAI ChatChat that knows the visitorEmail CampaignsEmail from real visits
PricingWhy vTiltDocs
Docs / Nuxt.js
Getting Started
OverviewInstallInitializeIdentify usersTrack eventsLogout & resetVerify eventsCommon mistakes
Guides
Event forwardingReverse proxyRealtime dashboardSite knowledge
Frontend frameworks
Next.jsNuxt.jsVue.jsReactReact RouterRemixGatsbySvelte / SvelteKitAstroAngularTanStack StartDocusaurus
Backend frameworks
NestJSHonoCloudflare WorkersDjangoFlaskLaravelPhoenixRuby on Rails
Backend languages
PythonPHPRubyElixirGoJava.NET / C#Rust
Stack guides
Vue + PHP
API Reference
Browser SDK
Script bundlesAutocaptureWeb VitalsSession recordingChat widgetFeature readinessRemote configurationDebug logging
Node SDK
Install & setupCapture, identify & aliasContext & shutdownGlobal properties & opt-outError tracking
MCP server
Guides
OverviewAuthenticationOAuthAgent skills (prompts)AI intelligenceSite knowledgeGoogle AdsMeta Ads
Client setup
CursorClaude DesktopVS CodeCodex

Getting Started

OverviewInstallInitializeIdentify usersTrack eventsLogout & resetVerify eventsCommon mistakes

Guides

Event forwardingReverse proxyRealtime dashboardSite knowledge
Next.jsNuxt.jsVue.jsReactReact RouterRemixGatsbySvelte / SvelteKitAstroAngularTanStack StartDocusaurus

API Reference

MCP server

On this page

On this page

  • 1. Runtime config
  • 2. Install & initialise
  • 3. Identify on every authenticated page load
  • 4. Server-side events from Nitro
  • Next steps
DocsGuidesFrontend frameworksNuxt.js

Nuxt.js

Last updated July 22, 2026

Integrate vTilt with Nuxt 3 / Nuxt 4 — npm package or inline script, identify on every authenticated page load, server-side events with Nitro.

vTilt drops into Nuxt 3/4 on the client. Nitro server routes can also emit events using the Node SDK so server actions and webhooks land on the same person record.

#1. Runtime config

Expose the token and ingest origin via nuxt.config.ts. The public block is readable on the client; values without public stay server-only.

// nuxt.config.ts
export default defineNuxtConfig({
  runtimeConfig: {
    vtiltTrackerToken: process.env.VTILT_TRACKER_TOKEN,
    public: {
      vtiltToken: process.env.NUXT_PUBLIC_VTILT_TOKEN,
      vtiltHost: process.env.NUXT_PUBLIC_VTILT_HOST,
    },
  },
})
typescript
# .env
NUXT_PUBLIC_VTILT_TOKEN=YOUR_PROJECT_TOKEN
NUXT_PUBLIC_VTILT_HOST=https://www.vtilt.com
VTILT_TRACKER_TOKEN=YOUR_PROJECT_TOKEN
text

#2. Install & initialise

Choose how you load the Browser SDK. npm boots the SDK from a client-only plugin; the inline script injects a stub via useHead with no package to install. Both expose the same window.vt global — the rest of this guide is identical either way.

Install the package:

npm install @v-tilt/browser
bash

Create plugins/vtilt.client.ts — the .client suffix keeps it out of SSR:

// plugins/vtilt.client.ts
import { vt } from '@v-tilt/browser'

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

  vt.init(config.public.vtiltToken, {
    api_host: config.public.vtiltHost,
    autocapture: true,
    capture_pageview: false, // captured on Vue Router navigation below
    capture_pageleave: true,
  })

  const router = useRouter()
  router.afterEach((to, from) => {
    vt.capture('$pageview', {
      $current_url: window.location.href,
      $pathname: to.fullPath,
      $referrer: from.fullPath,
    })
  })

  return { provide: { vt } }
})
typescript

Now useNuxtApp().$vt returns the SDK from any component.

Tip

Need chat on first paint? Swap array.js for array.chat.js and add chat: { enabled: true }. See Script bundles.

#3. Identify on every authenticated page load

Important

Identifying users only inside your login handler leaves every visitor with an existing session cookie anonymous. Identify on every page load when the user is known.

// plugins/vtilt-identify.client.ts
import { vt } from '@v-tilt/browser'

export default defineNuxtPlugin(() => {
  const user = useState<{ id: string; email: string } | null>('user')

  watchEffect(() => {
    if (user.value) {
      vt.identify(user.value.id, { email: user.value.email })
    }
  })
})
typescript

Note

Using the inline script? Replace vt with window.vt and drop the import.

See Identify & alias for the full model.

#4. Server-side events from Nitro

For events from server routes, install the Node SDK:

npm install @v-tilt/node
bash

Reuse a single client across requests:

// server/utils/vtilt.ts
import { VTiltNode } from '@v-tilt/node'

let _client: VTiltNode | null = null
export function vtilt() {
  if (!_client) {
    const cfg = useRuntimeConfig()
    _client = new VTiltNode(cfg.vtiltTrackerToken, {
      host: cfg.public.vtiltHost,
    })
  }
  return _client
}
typescript
// server/api/checkout.post.ts
import { vtilt } from '~/server/utils/vtilt'

export default defineEventHandler(async event => {
  const body = await readBody(event)

  vtilt().capture({
    distinctId: body.userId,
    event: 'purchase_completed',
    properties: { amount: body.amount },
  })

  await vtilt().shutdown()
  return { ok: true }
})
typescript

#Next steps

  • Vue + PHP integration guide — the same identify-on-page-load pattern with a PHP back-end.
  • Identify & alias — full identification model.
  • Reverse proxy — block-resistant ingestion.
  • Node SDK / Capture, identify & alias — server-side event shapes.
  • Common mistakes — integration pitfalls to avoid before you ship.
PreviousNext.jsIntegration guidesNextVue.jsIntegration guides