Astro
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#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/browserAstro <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>#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>
)
}---
import CtaButton from '../components/CtaButton'
---
<CtaButton client:load />#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>#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// 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,
})// 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 }))
}#Next steps
- Identify & alias — anonymous → known user merge.
- Autocapture — what's captured automatically.
- Node SDK — server-side event shapes.