vTilt
Why vTiltHow It WorksFeaturesFAQDocs
Docs / Session recording
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

SDK

InstallScript bundlesEvent trackingAutocaptureIdentify & aliasWeb VitalsSession recordingChat widgetFeature readinessRemote configurationReverse proxyDebug logging
DocsBrowser SDKSession recording

Session recording

Record and replay user sessions with privacy-aware masking.

Record and replay user sessions with privacy controls (mask inputs, block elements). Recording is opt-in and lazy-loaded — the rrweb-based replay extension only fetches when enabled.

Tip

Tip: To avoid a separate recorder.js request, load array.full.js or array.full.chat.js.

#Enable

Enable session_recording in init with optional privacy options:

vt.init('YOUR_PROJECT_TOKEN', {
  api_host: 'https://www.vtilt.com',
  session_recording: {
    enabled: true,
    maskAllInputs: true,
    sampleRate: 1.0,
    minimumDurationMs: 1000,
  },
})
typescript

#Options

OptionDefaultDescription
enabledfalseMaster switch. When false, the recording extension is never loaded.
maskAllInputstrueMask the value of every <input>, <textarea> and <select>. Strongly recommended unless you've audited your forms.
sampleRate1.0Fraction of sessions to record (0–1). Use 0.1 to record 10% of sessions.
minimumDurationMs1000Skip uploading the recording if the session is shorter than this (cuts noise from bounces).
blockSelector—Extra CSS selectors for rrweb block mode (same-sized placeholder, inner DOM not stored). Merged with built-in selectors below unless skipDefaultInvisibleBlocking is true.
skipDefaultInvisibleBlockingfalseWhen true, only your blockSelector / masking.blockSelector values apply; built-in blocking of .sr-only, Webflow w-condition-invisible, hidden inputs, etc. is disabled.

#Privacy

  • DOM mutations are captured and compressed with rrweb's incremental snapshot algorithm — no canvas captures, no media bytes, no clipboard.
  • Invisible template copy: By default, rrweb is configured to block serialization of common off-screen nodes (screen-reader-only classes, Webflow CMS condition placeholders, input[type="hidden"], etc.). They still occupy layout in replay as placeholders, but their inner text is not shipped. CSS-only hiding (e.g. display:none only in an external stylesheet) is not detectable at record time; server-side recording analysis still filters those cases.
  • Inputs, passwords and elements with data-vt-mask are masked at the source; the masked value never leaves the browser.
  • vt.startSessionRecording() / vt.stopSessionRecording() give you programmatic control if you need to gate recording on a feature flag or consent screen.
  • Recording snapshots arrive at /api/s on a separate batch key from regular events, so you can route them to a different bucket / region for compliance.
PreviousWeb VitalsBrowser SDKNextChat widgetBrowser SDK

On this page

  • Enable
  • Options
  • Privacy