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 / Script bundles
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

Script bundlesAutocaptureWeb VitalsSession recordingChat widgetFeature readinessRemote configurationDebug logging

MCP server

On this page

On this page

  • Quick picker
  • How lazy loading works
  • Script-tag bundles (IIFE)
  • array.js — core only (default)
  • array.chat.js — core + chat
  • array.full.js — core + recorder + web vitals
  • array.full.chat.js — core + recorder + web vitals + chat
  • .no-external variants
  • npm / ESM bundles
  • Lazy extension files
  • CDN and script_host
  • Full reference
DocsAPI ReferenceBrowser SDKScript bundles

Script bundles

Last updated July 22, 2026

Choose the right browser SDK bundle — default lazy loading, chat-ready, or full single-file builds for script tags and npm.

The browser SDK ships as several pre-built files under /dist/. The default snippet loads array.js — a lightweight core that fetches optional features (chat.js, recorder.js, web-vitals.js) only when you enable them.

Pick a combined bundle when you want zero extra network requests for a feature, or when you call APIs like vt.sendChatMessage() immediately after page load.

#Quick picker

Your situationUse
Standard analytics sitearray.js (default snippet)
Chat widget with hero CTAs / instant sendChatMessage()array.chat.js
Session recording + web vitals, no lazy fetchesarray.full.js
Chat + recording + web vitals in one filearray.full.chat.js
npm / Vite / webpack appmodule.es.js or a module.*.es variant

#How lazy loading works

  1. The core bundle includes thin wrappers (ChatWrapper, session recording wrapper, …).
  2. When a feature needs its heavy code, the SDK checks window.__VTiltExtensions__.
  3. If the factory is missing, it loads {api_host}/dist/{feature}.js (or {script_host}/{feature}.js when script_host is set).
  4. If the factory is already present (combined bundle), no network request is made.

All public methods (vt.openChat(), vt.sendChatMessage(), vt.updateConfig(), …) are safe to call before the heavy code is ready — the SDK queues calls internally.

Script tag only: those methods must appear in the inline stub's method list (see Install — Script tag vs npm). npm imports do not use a stub; import vt from @v-tilt/browser or a module.*.es bundle and call methods directly.

#Script-tag bundles (IIFE)

Files are served from https://www.vtilt.com/dist/ on self-hosted setups, or from your script_host CDN when configured.

#array.js — core only (default)

<script src="https://www.vtilt.com/dist/array.js"></script>
html

Lazy-loads chat.js, recorder.js, and web-vitals.js on demand. Smallest initial download.

#array.chat.js — core + chat

Equivalent to loading array.js and chat.js together. Use when chat is enabled and visitors may open it immediately after page load.

<script src="https://www.vtilt.com/dist/array.chat.js"></script>
<script>
  vt.init('YOUR_PROJECT_TOKEN', {
    api_host: 'https://www.vtilt.com',
    chat: { enabled: true },
  })
</script>
html

See also Chat widget.

#array.full.js — core + recorder + web vitals

Pre-registers session recording and web vitals. Does not include chat (same split PostHog uses for conversations — chat is large and optional).

<script src="https://www.vtilt.com/dist/array.full.js"></script>
html

Pair with disable_external_dependency_loading: true if you never want runtime script injection:

vt.init('YOUR_PROJECT_TOKEN', {
  api_host: 'https://www.vtilt.com',
  disable_external_dependency_loading: true,
})
typescript

#array.full.chat.js — core + recorder + web vitals + chat

Single file when you need every optional browser feature pre-bundled.

<script src="https://www.vtilt.com/dist/array.full.chat.js"></script>
html

#.no-external variants

FileSame asUse with
array.full.no-external.jsarray.full.jsdisable_external_dependency_loading: true
array.chat.no-external.jsarray.chat.jsdisable_external_dependency_loading: true
array.full.chat.no-external.jsarray.full.chat.jsdisable_external_dependency_loading: true

#npm / ESM bundles

When you install @v-tilt/browser, the same artifacts live under dist/:

ImportPre-registered
@v-tilt/browser → module.es.js— (lazy)
@v-tilt/browser/dist/module.chat.eschat
@v-tilt/browser/dist/module.full.esrecorder, web vitals
@v-tilt/browser/dist/module.full.chat.esrecorder, web vitals, chat

Default lazy import:

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

vt.init('YOUR_PROJECT_TOKEN', { api_host: 'https://www.vtilt.com' })
typescript

Chat-ready single import:

import { vt } from '@v-tilt/browser/dist/module.chat.es'

vt.init('YOUR_PROJECT_TOKEN', {
  api_host: 'https://www.vtilt.com',
  chat: { enabled: true },
})
typescript

Or side-effect-import an extension before the core (PostHog-style):

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

vt.init('YOUR_PROJECT_TOKEN', { api_host: 'https://www.vtilt.com', chat: { enabled: true } })
typescript

#Lazy extension files

These register on __VTiltExtensions__ and are fetched automatically when needed (unless you use a combined bundle above):

FileFeature
chat.jsChat widget
recorder.jsSession recording
web-vitals.jsWeb Vitals

#CDN and script_host

By default, lazy extensions load from {api_host}/dist/{name}.js. Set script_host to serve bundles from a CDN (no /dist/ prefix):

vt.init('YOUR_PROJECT_TOKEN', {
  api_host: 'https://www.vtilt.com',
  script_host: 'https://cdn.example.com',
})
// Lazy chat loads from: https://cdn.example.com/chat.js
// Core snippet should load: https://cdn.example.com/array.js
typescript

#Full reference

BundleFormatPre-registered extensions
array.jsIIFE—
array.chat.jsIIFEchat
array.full.jsIIFErecorder, web-vitals
array.full.chat.jsIIFErecorder, web-vitals, chat
module.es.jsESM—
module.chat.es.jsESMchat
module.full.es.jsESMrecorder, web-vitals
module.full.chat.es.jsESMrecorder, web-vitals, chat
main.jsCJS— (lazy)
PreviousVue + PHPIntegration guidesNextAutocaptureBrowser SDK