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 / Common mistakes
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

API Reference

MCP server

On this page

On this page

  • Calling identify() only at login time
  • Calling resetUser() on anonymous page loads
  • Loading the SDK twice (inline stub and npm)
  • Initializing too late
  • Wrong or missing project token
  • Ad-blocker blocking ingest
  • Event naming that breaks dashboards
  • Mixing identify() ids in one session
  • Using email as the distinct id
  • Skipping verification
DocsGetting StartedCommon mistakes

Common mistakes

Last updated July 22, 2026

Integration pitfalls to avoid — identify on login only, premature resetUser(), wrong install path, init timing, ad-blockers, and event naming.

The mistakes below account for most broken vTilt integrations. AI agents should read this page before shipping — it is the single canonical pitfalls URL.

#Calling identify() only at login time

Warning

This mistake is especially common when adding vTilt to a product that is already in production. Returning users are already logged in — your login-success handler does not run for them. If identify() is wired only there, vTilt keeps those users anonymous until they log out and back in.

Fix: Call vt.identify(currentUser.id, { … }) on every page load when the user is already logged in — wherever your app resolves auth (after vt.init() or when your session hook finishes loading), not only in the login-success handler. The call is idempotent. See Identify users.

#Calling resetUser() on anonymous page loads

Warning

resetUser() whenever user is null — including before auth finishes loading — clears anonymous identity on every visit.

Fix: Wait for loading === false. Reset only when getUserState() === 'identified' and the app user is null (real sign-out). See Logout & reset.

#Loading the SDK twice (inline stub and npm)

Warning

Both the inline script stub and importing @v-tilt/browser in the same app loads the SDK twice and can fire duplicate events or call init() more than once.

Fix: Pick one install path — see Install. Both are fully supported; the inline script is the recommended default, and the npm package is a great fit for bundled apps. Just don't combine them.

#Initializing too late

Warning

Calling vt.init() after navigation or in a lazy-loaded chunk misses early pageviews and can race with identify().

Fix: Run init() in <head> (script stub), beforeInteractive (Next.js), or your app entry before paint. See Initialize the SDK.

#Wrong or missing project token

Warning

A typo in the token or loading the SDK on a domain not allowed for the project produces silent 401s or empty Debug View.

Fix: Copy the token from Settings → Project in the dashboard. Check Verify events.

#Ad-blocker blocking ingest

Warning

Browser extensions block requests to known analytics hostnames.

Fix: Route traffic through your own domain with a reverse proxy. The SDK logs a warning pointing at that guide when transport fails repeatedly.

#Event naming that breaks dashboards

Warning

Spaces, camelCase, or PascalCase in event names (Button Clicked, purchaseComplete) fragment reports.

Fix: Use snake_case verbs (button_clicked, purchase_completed). See Track events.

#Mixing identify() ids in one session

Warning

Calling identify() with different ids in the same session triggers unexpected person merges.

Fix: Use your stable internal user id (UUID, integer). Use alias() to link two known ids. Call resetUser() between distinct users on a shared device.

#Using email as the distinct id

Warning

Emails change; merges become painful.

Fix: Use your internal user id. Attach email as a property: vt.identify(user.id, { email: user.email }).

#Skipping verification

Warning

Shipping without confirming $pageview in Debug View means you discover bugs in production.

Fix: Open Verify events, reload your site, and confirm a live $pageview within ~2 seconds.

PreviousVerify eventsGetting StartedNextEvent forwardingGuides