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 / React
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. Add your environment variables
  • 2. Install & initialise
  • 3. Capture events from any component
  • 4. Pageviews for client-side routers
  • Next steps
DocsGuidesFrontend frameworksReact

React

Last updated July 22, 2026

Integrate vTilt into a standalone React app (Vite, Create React App, or any React renderer) — npm package or inline script, identify on auth state changes.

vTilt drops into any React app — Vite, CRA, RSPack, or a custom Webpack setup. Initialise the SDK once on startup, then identify the user whenever your auth state changes.

Tip

Using a React framework? Reach for the dedicated guide instead — Next.js, Remix, React Router, TanStack Start, Gatsby.

#1. Add your environment variables

# .env
VITE_VTILT_TOKEN=YOUR_PROJECT_TOKEN
VITE_VTILT_HOST=https://www.vtilt.com
text

#2. Install & initialise

Choose how you load the Browser SDK. npm boots the SDK from a provider component; the inline script drops a stub in index.html 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

Initialise the SDK in a provider that identifies the user when auth is ready:

// src/lib/vtilt.tsx
import { useEffect } from 'react'
import { vt } from '@v-tilt/browser'
import { useAuth } from '../auth'

export function VTiltProvider({ children }: { children: React.ReactNode }) {
  const { user, isLoading } = useAuth()

  useEffect(() => {
    vt.init(import.meta.env.VITE_VTILT_TOKEN, {
      api_host: import.meta.env.VITE_VTILT_HOST,
      autocapture: true,
      capture_pageview: true,
      capture_pageleave: true,
    })
  }, [])

  useEffect(() => {
    if (isLoading) return
    if (user?.id) {
      vt.identify(user.id, { email: user.email })
    } else if (vt.getUserState() === 'identified') {
      vt.resetUser()
    }
  }, [user, isLoading])

  return <>{children}</>
}
tsx
// src/main.tsx
import ReactDOM from 'react-dom/client'
import { VTiltProvider } from './lib/vtilt'
import App from './App'

ReactDOM.createRoot(document.getElementById('root')!).render(
  <VTiltProvider>
    <App />
  </VTiltProvider>,
)
tsx

useAuth() is your app's hook — any shape with { user, isLoading } works (Clerk, Auth0, Supabase, custom context).

Important

Wait for isLoading === false before identify() or resetUser(). Reset only when getUserState() === 'identified' — not on every render where user is null. See Identify → Real-world examples.

Tip

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

#3. Capture events from any component

import { vt } from '@v-tilt/browser'

export function CtaButton() {
  return (
    <button onClick={() => vt.capture('cta_clicked', { location: 'hero' })}>
      Get started
    </button>
  )
}
tsx

Note

With the inline script, vt is on window — skip the import.

#4. Pageviews for client-side routers

Most SPA routers update the History API on navigation, which the SDK picks up automatically. If yours doesn't (rare), emit a pageview from a route effect:

import { useLocation } from 'react-router'

function PageviewTracker() {
  const location = useLocation()
  useEffect(() => {
    vt.capture('$pageview', {
      $current_url: window.location.href,
      $pathname: location.pathname,
    })
  }, [location.pathname])
  return null
}
tsx

#Next steps

  • Identify & alias — anonymous → known user merge.
  • Autocapture — what's captured automatically.
  • Reverse proxy — block-resistant ingestion.
  • Common mistakes — integration pitfalls to avoid before you ship.
PreviousVue.jsIntegration guidesNextReact RouterIntegration guides