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 / Astro
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. Add your environment variables
  • 2. Install & initialise
  • 3. Capture events from islands
  • 4. Astro view transitions
  • 5. Server-side events from API routes (SSR mode)
  • Next steps
DocsGuidesFrontend frameworksAstro

Astro

Last updated July 22, 2026

Integrate vTilt with Astro — npm package or inline script in your base layout, framework-island compatibility, server-side events.

Astro is islands-first: most of the page is static HTML and you opt into JS only where you need interactivity. vTilt fits in via a top-level <script> in your base layout, so every page boots the SDK without an island wrapper.

#1. Add your environment variables

# .env
PUBLIC_VTILT_TOKEN=YOUR_PROJECT_TOKEN
PUBLIC_VTILT_HOST=https://www.vtilt.com
text

#2. Install & initialise

Choose how you load the Browser SDK. npm uses a bundled <script> in your layout; the inline script uses an is:inline stub 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

Astro <script> tags are bundled and treeshaken by Vite. Add one in your shared layout so every page initialises the SDK and identifies the user:

---
// src/layouts/Base.astro
const { user = null } = Astro.props
---
<!doctype html>
<html lang="en">
  <head>
    <slot name="head" />
    <script type="module" define:vars={{ user }}>
      import { vt } from '@v-tilt/browser'

      vt.init(import.meta.env.PUBLIC_VTILT_TOKEN, {
        api_host: import.meta.env.PUBLIC_VTILT_HOST,
        autocapture: true,
        capture_pageview: true,
        capture_pageleave: true,
      })

      if (user) vt.identify(user.id, { email: user.email })
    </script>
  </head>
  <body>
    <slot />
  </body>
</html>
astro

Important

Identifying users in the layout means every authenticated page load identifies — not just the login event. See Identify & alias for the full model.

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 islands

With the npm package, import vt in islands. With the inline script, use window.vt.

// src/components/CtaButton.tsx
import { vt } from '@v-tilt/browser'

export default function CtaButton() {
  return (
    <button onClick={() => vt.capture('cta_clicked', { location: 'hero' })}>
      Get started
    </button>
  )
}
tsx
---
import CtaButton from '../components/CtaButton'
---
<CtaButton client:load />
astro

#4. Astro view transitions

If you use Astro view transitions, the page doesn't fully reload on navigation. Re-emit $pageview from the astro:after-swap event:

<script>
  import { vt } from '@v-tilt/browser'
  document.addEventListener('astro:after-swap', () => {
    vt.capture('$pageview', { $current_url: window.location.href })
  })
</script>
html

#5. Server-side events from API routes (SSR mode)

For events from SSR pages and API routes, install the Node SDK:

npm install @v-tilt/node
bash
// src/lib/vtilt.ts
import { VTiltNode } from '@v-tilt/node'

export const vtilt = new VTiltNode(import.meta.env.VTILT_TRACKER_TOKEN, {
  host: import.meta.env.PUBLIC_VTILT_HOST,
})
typescript
// src/pages/api/checkout.ts
import type { APIRoute } from 'astro'
import { vtilt } from '../../lib/vtilt'

export const POST: APIRoute = async ({ request }) => {
  const { userId, amount } = await request.json()
  vtilt.capture({
    distinctId: userId,
    event: 'purchase_completed',
    properties: { amount },
  })
  await vtilt.shutdown()
  return new Response(JSON.stringify({ ok: true }))
}
typescript

#Next steps

  • Identify & alias — anonymous → known user merge.
  • Autocapture — what's captured automatically.
  • Node SDK — server-side event shapes.
  • Common mistakes — integration pitfalls to avoid before you ship.
PreviousSvelte / SvelteKitIntegration guidesNextAngularIntegration guides