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 / Angular
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. Install & initialise
  • 2. Router pageviews
  • 3. Identify users
  • 4. Capture events anywhere
  • Next steps
DocsGuidesFrontend frameworksAngular

Angular

Last updated July 22, 2026

Integrate vTilt with Angular 16+ — npm package or inline script, Router pageviews, identify on every page load.

vTilt drops into Angular through an APP_INITIALIZER (or an inline script), plus a Router subscription that emits a pageview on every navigation. Works with both the classic NgModule setup and the standalone bootstrapApplication API.

#1. Install & initialise

Choose how you load the Browser SDK. npm boots the SDK from an APP_INITIALIZER; 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

Provide a function that runs on app boot and calls vt.init(). Read the token via environment.ts to keep it out of source:

// src/app/vtilt.ts
import { APP_INITIALIZER, Provider } from '@angular/core'
import { vt } from '@v-tilt/browser'
import { environment } from '../environments/environment'

export const VTILT_INIT: Provider = {
  provide: APP_INITIALIZER,
  multi: true,
  useFactory: () => () => {
    vt.init(environment.vtiltToken, {
      api_host: environment.vtiltHost,
      autocapture: true,
      capture_pageview: false,
      capture_pageleave: true,
    })
  },
}
typescript
// src/environments/environment.ts
export const environment = {
  vtiltToken: 'YOUR_PROJECT_TOKEN',
  vtiltHost: 'https://www.vtilt.com',
}
typescript

Register it on bootstrap:

// src/main.ts
import { bootstrapApplication } from '@angular/platform-browser'
import { provideRouter } from '@angular/router'
import { AppComponent } from './app/app.component'
import { VTILT_INIT } from './app/vtilt'
import { routes } from './app/routes'

bootstrapApplication(AppComponent, {
  providers: [provideRouter(routes), VTILT_INIT],
})
typescript

For NgModule apps, add VTILT_INIT to the providers array of AppModule.

Tip

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

#2. Router pageviews

Subscribe to NavigationEnd events and emit $pageview so SPA navigation registers in vTilt.

// src/app/app.component.ts
import { Component, OnInit, inject } from '@angular/core'
import { Router, NavigationEnd, RouterOutlet } from '@angular/router'
import { filter } from 'rxjs/operators'
import { vt } from '@v-tilt/browser'

@Component({
  standalone: true,
  selector: 'app-root',
  imports: [RouterOutlet],
  template: '<router-outlet></router-outlet>',
})
export class AppComponent implements OnInit {
  private router = inject(Router)

  ngOnInit() {
    this.router.events
      .pipe(filter(e => e instanceof NavigationEnd))
      .subscribe((e: NavigationEnd) => {
        vt.capture('$pageview', {
          $current_url: window.location.href,
          $pathname: e.urlAfterRedirects,
        })
      })
  }
}
typescript

Note

Using the inline script? Replace vt with window.vt and drop the import.

#3. Identify users

Identify whenever your auth service emits a user. The pattern below also identifies on app boot when the user is already logged in.

// src/app/auth.service.ts
import { Injectable } from '@angular/core'
import { BehaviorSubject } from 'rxjs'
import { vt } from '@v-tilt/browser'

@Injectable({ providedIn: 'root' })
export class AuthService {
  user$ = new BehaviorSubject<{ id: string; email: string } | null>(null)

  constructor() {
    this.user$.subscribe(user => {
      if (user) vt.identify(user.id, { email: user.email })
    })
  }

  logout() {
    vt.capture('user_logged_out')
    vt.resetUser()
    this.user$.next(null)
  }
}
typescript

Important

Make sure your auth service hydrates from the session cookie on app boot, not only after a successful login. Otherwise visitors who already have a session stay anonymous. See Identify & alias for the full model.

#4. Capture events anywhere

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

@Component({
  /* ... */
})
export class HeroComponent {
  onCta() {
    vt.capture('cta_clicked', { location: 'hero' })
  }
}
typescript

#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.
PreviousAstroIntegration guidesNextTanStack StartIntegration guides