Installation
npm install --save @outlit/browser
Quick Start
Initialize Outlit in your root layout:
// src/routes/+layout.ts
import outlit from '@outlit/browser'
import { browser } from '$app/environment'
import { PUBLIC_OUTLIT_KEY } from '$env/static/public'
if ( browser ) {
outlit . init ({
publicKey: PUBLIC_OUTLIT_KEY ,
trackPageviews: true ,
})
}
export const prerender = true
export const ssr = false
Add your public key to .env: PUBLIC_OUTLIT_KEY=pk_your_public_key_here
Alternative: Layout Component
Initialize in the layout component:
<!-- src/routes/+layout.svelte -->
< script >
import { browser } from '$app/environment'
import { PUBLIC_OUTLIT_KEY } from '$env/static/public'
import outlit from '@outlit/browser'
import { onMount } from 'svelte'
onMount (() => {
if ( browser ) {
outlit . init ({
publicKey: PUBLIC_OUTLIT_KEY ,
trackPageviews: true ,
})
}
})
</ script >
< slot />
Tracking Events
Track events in your components:
<!-- src/routes/pricing/+page.svelte -->
< script >
import outlit from '@outlit/browser'
function handleCheckout () {
outlit . track ( 'checkout_started' , {
plan: 'pro' ,
amount: 99
})
}
</ script >
< button on : click = { handleCheckout } >
Start Free Trial
</ button >
Identifying Users
Identify users after authentication:
<!-- src/routes/login/+page.svelte -->
< script >
import { goto } from '$app/navigation'
import outlit from '@outlit/browser'
let email = ''
let password = ''
async function handleLogin () {
const response = await fetch ( '/api/auth/login' , {
method: 'POST' ,
headers: { 'Content-Type' : 'application/json' },
body: JSON . stringify ({ email , password })
})
const user = await response . json ()
outlit . identify ({
email: user . email ,
userId: user . id ,
traits: {
name: user . name ,
plan: user . plan
}
})
goto ( '/dashboard' )
}
</ script >
< form on : submit | preventDefault = { handleLogin } >
< input bind : value = { email } type = "email" placeholder = "Email" />
< input bind : value = { password } type = "password" placeholder = "Password" />
< button type = "submit" > Login </ button >
</ form >
Navigation Tracking
Track navigation with SvelteKit’s stores:
<!-- src/routes/+layout.svelte -->
< script >
import { afterNavigate } from '$app/navigation'
import { browser } from '$app/environment'
import outlit from '@outlit/browser'
import { onMount } from 'svelte'
onMount (() => {
if ( browser ) {
outlit . init ({
publicKey: PUBLIC_OUTLIT_KEY ,
trackPageviews: false , // Manual tracking
})
}
})
afterNavigate (({ to }) => {
if ( browser && to ) {
outlit . track ( 'pageview' , {
path: to . url . pathname ,
params: to . params
})
}
})
</ script >
< slot />
Load Function Integration
Track events from load functions:
// src/routes/product/[id]/+page.ts
import type { PageLoad } from './$types'
export const load : PageLoad = async ({ params , fetch }) => {
const product = await fetch ( `/api/products/ ${ params . id } ` ). then ( r => r . json ())
// Track on server
await fetch ( '/api/track' , {
method: 'POST' ,
headers: { 'Content-Type' : 'application/json' },
body: JSON . stringify ({
event: 'product_viewed' ,
properties: { productId: params . id }
})
})
return { product }
}
Server-Side Tracking
Track events from API routes:
// src/routes/api/track/+server.ts
import { json } from '@sveltejs/kit'
import type { RequestHandler } from './$types'
import { Outlit } from '@outlit/node'
import { OUTLIT_PRIVATE_KEY } from '$env/static/private'
const outlit = new Outlit ({
privateKey: OUTLIT_PRIVATE_KEY
})
export const POST : RequestHandler = async ({ request }) => {
const { event , properties , visitorId } = await request . json ()
await outlit . track ({
visitorId ,
event ,
properties
})
return json ({ success: true })
}
Auth Integration
With Lucia
<!-- src/routes/+layout.svelte -->
< script >
import { browser } from '$app/environment'
import { page } from '$app/stores'
import outlit from '@outlit/browser'
import { onMount } from 'svelte'
onMount (() => {
if ( browser ) {
outlit . init ({
publicKey: PUBLIC_OUTLIT_KEY ,
trackPageviews: true ,
})
}
})
$ : if ( browser && $ page . data . user ) {
outlit . setUser ({
email: $ page . data . user . email ,
userId: $ page . data . user . id ,
traits: {
name: $ page . data . user . name
}
})
} else if ( browser && ! $ page . data . user ) {
outlit . clearUser ()
}
</ script >
< slot />
Track contact lifecycle events:
< script >
import outlit from '@outlit/browser'
import { onMount } from 'svelte'
onMount (() => {
// Track activation after onboarding
outlit . user . activate ({ flow: 'onboarding' , step: 'completed' })
})
function handleEngagementMilestone () {
outlit . user . engaged ({ milestone: 'first_project' })
}
</ script >
< button on : click = { handleEngagementMilestone } >
Complete First Project
</ button >
Stage methods (user.activate, user.engaged) require the user to be identified first using setUser() or identify().
Account billing (paid, churned, trialing) is tracked separately. If you’ve connected Stripe, billing is automatic. For manual billing, see Stages & Billing .
Consent Management
Handle user consent:
<!-- src/lib/components/CookieBanner.svelte -->
< script >
import { browser } from '$app/environment'
import outlit from '@outlit/browser'
import { onMount } from 'svelte'
let showBanner = false
onMount (() => {
if ( browser ) {
const hasConsent = localStorage . getItem ( 'tracking-consent' )
showBanner = hasConsent !== 'true'
}
})
function acceptTracking () {
localStorage . setItem ( 'tracking-consent' , 'true' )
outlit . enableTracking ()
showBanner = false
}
</ script >
{# if showBanner }
< div class = "cookie-banner" >
< p > We use cookies to improve your experience. </ p >
< button on : click = { acceptTracking } > Accept </ button >
</ div >
{/ if }
Initialize without auto-tracking:
// src/routes/+layout.ts
import outlit from '@outlit/browser'
import { browser } from '$app/environment'
import { PUBLIC_OUTLIT_KEY } from '$env/static/public'
if ( browser ) {
outlit . init ({
publicKey: PUBLIC_OUTLIT_KEY ,
autoTrack: false , // Wait for consent
})
}
Stores Integration
Create a store for Outlit:
// src/lib/stores/outlit.ts
import { writable } from 'svelte/store'
import outlit from '@outlit/browser'
function createOutlitStore () {
const { subscribe } = writable ( outlit )
return {
subscribe ,
track : ( eventName : string , properties ?: Record < string , any >) => {
outlit . track ( eventName , properties )
},
identify : ( options : { email ?: string ; userId ?: string ; traits ?: Record < string , any > }) => {
outlit . identify ( options )
},
setUser : ( identity : { email ?: string ; userId ?: string ; traits ?: Record < string , any > }) => {
outlit . setUser ( identity )
},
clearUser : () => {
outlit . clearUser ()
},
user: outlit . user ,
}
}
export const outlitStore = createOutlitStore ()
Use in components:
< script >
import { outlitStore } from '$lib/stores/outlit'
function handleClick () {
outlitStore . track ( 'button_clicked' , { button: 'cta' })
}
</ script >
< button on : click = { handleClick } >
Click Me
</ button >
Environment Variables
Configure environment variables:
# .env
# Public key (used in browser)
PUBLIC_OUTLIT_KEY = pk_your_public_key_here
# Private key (used in server API routes)
OUTLIT_PRIVATE_KEY = sk_your_private_key_here
Never expose your private key in client-side code. Only use it in server-side API routes.
TypeScript Support
Full TypeScript support is included:
import outlit , { type OutlitOptions } from '@outlit/browser'
const options : OutlitOptions = {
publicKey: PUBLIC_OUTLIT_KEY ,
trackPageviews: true ,
flushInterval: 5000
}
outlit . init ( options )
Next Steps
Server-Side Tracking Track events from your backend
Identity Resolution Learn how profiles are merged
NPM Package Full API reference
React Integration Use Outlit with React