vTilt
Why vTiltHow It WorksFeaturesFAQDocs
Docs / React
Quick startEvent forwarding
MCP server
Guides
OverviewAuthenticationOAuthAgent skills (prompts)AI intelligenceGoogle Ads
Client setup
CursorClaude DesktopVS CodeCodex
Realtime
Debug ViewRealtime Dashboard
Integration guides
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
SDK
Browser SDK
InstallScript bundlesEvent trackingAutocaptureIdentify & aliasWeb VitalsSession recordingChat widgetFeature readinessRemote configurationReverse proxyDebug logging
Node SDK
Install & setupCapture, identify & aliasContext & shutdown

Documentation

vTilt
Quick startEvent forwarding

MCP server

Realtime

Debug ViewRealtime Dashboard

Integration guides

Next.jsNuxt.jsVue.jsReactReact RouterRemixGatsbySvelte / SvelteKitAstroAngularTanStack StartDocusaurus

SDK

DocsIntegration guidesReact

React

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

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 also identifies the user on auth changes:

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

export function VTiltProvider({
  user,
  children,
}: {
  user: { id: string; email: string } | null
  children: React.ReactNode
}) {
  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 (user) vt.identify(user.id, { email: user.email })
  }, [user])

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

function Root() {
  const { user } = useAuth()
  return (
    <VTiltProvider user={user}>
      <App />
    </VTiltProvider>
  )
}

ReactDOM.createRoot(document.getElementById('root')!).render(<Root />)
tsx

Important

Important: The effect watching user re-runs on every auth state change — including first render when the user is hydrated from a session cookie. That's the only way to identify visitors who arrive with an existing session, not just users who freshly log in.

Tip

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

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.
PreviousVue.jsIntegration guidesNextReact RouterIntegration guides

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