Installation
npm install --save @outlit/browser
Quick Start
Install the OutlitPlugin in your app’s entry point and use composables in components.
If your app has user authentication, use the useOutlitUser composable to automatically sync user identity. This is the recommended approach as it automatically handles login/logout transitions.// main.ts
import { createApp } from 'vue'
import { OutlitPlugin } from '@outlit/browser/vue'
import App from './App.vue'
const app = createApp(App)
app.use(OutlitPlugin, {
publicKey: import.meta.env.VITE_OUTLIT_KEY,
trackPageviews: true,
})
app.mount('#app')
<!-- App.vue -->
<script setup>
import { computed } from 'vue'
import { useOutlitUser } from '@outlit/browser/vue'
import { useAuthStore } from '@/stores/auth'
const auth = useAuthStore()
// Build user identity from your auth state
const outlitUser = computed(() => {
if (!auth.user) return null
return {
email: auth.user.email,
userId: auth.user.id,
traits: {
name: auth.user.name,
plan: auth.user.plan
}
}
})
// Auto-sync user identity with Outlit
useOutlitUser(outlitUser)
</script>
<template>
<router-view />
</template>
For marketing sites without authentication, just install the plugin:// main.ts
import { createApp } from 'vue'
import { OutlitPlugin } from '@outlit/browser/vue'
import App from './App.vue'
const app = createApp(App)
app.use(OutlitPlugin, {
publicKey: import.meta.env.VITE_OUTLIT_KEY,
trackPageviews: true,
})
app.mount('#app')
Set your public key in .env:VITE_OUTLIT_KEY=pk_your_public_key_here
Using the Composable
Track custom events with the useOutlit composable:
<script setup>
import { useOutlit } from '@outlit/browser/vue'
const { track } = useOutlit()
function handlePricingClick() {
track('pricing_clicked', { plan: 'pro' })
}
</script>
<template>
<button @click="handlePricingClick">
View Pricing
</button>
</template>
Plugin Configuration
OutlitPlugin
The OutlitPlugin initializes tracking and provides context to all components.
import { OutlitPlugin } from '@outlit/browser/vue'
app.use(OutlitPlugin, {
publicKey: 'pk_xxx',
apiHost: 'https://app.outlit.ai',
trackPageviews: true,
trackForms: true,
trackEngagement: true,
formFieldDenylist: ['custom_secret_field'],
flushInterval: 5000,
})
Options
Your organization’s public key.
apiHost
string
default:"https://app.outlit.ai"
API endpoint for sending events.
Automatically track pageviews on route changes.
Automatically capture form submissions.
Additional field names to exclude from form capture.
How often to flush queued events (ms).
Whether to start tracking automatically. Set to false to wait for user consent. Use enableTracking() from the useOutlit composable after consent.
Automatically identify users when they submit forms containing an email field. Set to false to disable and call identify() manually.
Track engagement metrics (active time on page).
Idle timeout in milliseconds for engagement tracking.
Track booking events from calendar embeds (Cal.com, Calendly).
User Identity Patterns
The useOutlitUser composable is the recommended way to handle user identity. It’s simpler and more reliable than manual identify() calls because:
- Automatic lifecycle management: Login/logout transitions are handled automatically
- Reactive: Uses Vue’s reactivity system to sync with your auth state
- Cleaner code: No need for watchers with manual
setUser() calls
Pattern 1: With Pinia Store
<!-- App.vue or a top-level component -->
<script setup>
import { computed } from 'vue'
import { useOutlitUser } from '@outlit/browser/vue'
import { useUserStore } from '@/stores/user'
const userStore = useUserStore()
const outlitUser = computed(() => {
if (!userStore.user) return null
return {
email: userStore.user.email,
userId: userStore.user.id,
traits: {
name: userStore.user.name,
plan: userStore.user.plan
}
}
})
// Automatically syncs when userStore.user changes
useOutlitUser(outlitUser)
</script>
Pattern 2: With Composable Auth
<script setup>
import { computed } from 'vue'
import { useOutlitUser } from '@outlit/browser/vue'
import { useAuth } from '@/composables/useAuth'
const { user, isAuthenticated } = useAuth()
const outlitUser = computed(() => {
if (!isAuthenticated.value || !user.value) return null
return {
email: user.value.email,
userId: user.value.id,
traits: { name: user.value.name }
}
})
useOutlitUser(outlitUser)
</script>
When the user ref changes (login/logout), useOutlitUser automatically calls setUser() or clearUser() internally. You don’t need to call these methods manually.
Composables
useOutlit
The primary composable for tracking events and identifying users.
<script setup>
import { useOutlit } from '@outlit/browser/vue'
const {
track,
identify,
setUser,
clearUser,
user, // User stage methods: identify, activate, engaged, inactive
customer, // Customer billing methods: trialing, paid, churned
getVisitorId,
isInitialized,
isTrackingEnabled,
enableTracking,
disableTracking,
} = useOutlit()
// Track an event
track('button_clicked', { buttonId: 'cta' })
// Identify the user
identify({ email: 'user@example.com', traits: { plan: 'pro' } })
// User stage methods
user.activate({ flow: 'onboarding' })
user.engaged({ milestone: 'first_project' })
// Customer billing methods (requires account identifier)
customer.paid({ domain: 'acme.com', plan: 'pro' })
// Get visitor ID (null if tracking not enabled)
const visitorId = getVisitorId()
</script>
Returns
track
(eventName: string, properties?: object) => void
Track a custom event.
identify
(options: IdentifyOptions) => void
Identify the current visitor.
setUser
(identity: UserIdentity) => void
Set the current user identity. Ideal for SPA authentication flows.
Clear the current user identity (on logout).
User stage methods namespace:
user.identify(options) - Identify the user
user.activate(properties?) - Mark user as activated
user.engaged(properties?) - Mark user as engaged
user.inactive(properties?) - Mark user as inactive
Customer billing methods namespace. Requires at least one of domain, customerId, or stripeCustomerId:
customer.trialing(options) - Mark account as trialing
customer.paid(options) - Mark account as paid
customer.churned(options) - Mark account as churned
Get the current visitor’s ID. Returns null if tracking is not enabled.
Whether tracking is currently enabled. Will be false if autoTrack is false and enableTracking() hasn’t been called.
Enable tracking. Call this after obtaining user consent. Only needed if autoTrack is false.
Disable tracking and flush any pending events. Use this when a user declines or revokes consent.
Whether the tracker is ready.
useTrack
A convenience composable that returns just the track function:
<script setup>
import { useTrack } from '@outlit/browser/vue'
const track = useTrack()
</script>
<template>
<button @click="track('feature_clicked', { featureId: '123' })">
Try Feature
</button>
</template>
useIdentify
A convenience composable that returns just the identify function:
<script setup>
import { useIdentify } from '@outlit/browser/vue'
const identify = useIdentify()
async function handleLogin(email, password) {
const user = await login(email, password)
identify({
email: user.email,
userId: user.id,
traits: {
name: user.name,
plan: user.plan
}
})
}
</script>
useOutlitUser
Automatically syncs a reactive user ref with Outlit:
<script setup>
import { ref, computed } from 'vue'
import { useOutlitUser } from '@outlit/browser/vue'
// Your auth state
const currentUser = ref(null)
// Auto-sync with Outlit - handles login/logout automatically
useOutlitUser(currentUser)
// When user logs in
async function onLogin(credentials) {
const user = await api.login(credentials)
currentUser.value = {
email: user.email,
userId: user.id,
traits: { name: user.name, plan: user.plan }
}
}
// When user logs out
function onLogout() {
currentUser.value = null
}
</script>
Consent Management
If you need to wait for user consent before tracking:
// main.ts
app.use(OutlitPlugin, {
publicKey: import.meta.env.VITE_OUTLIT_KEY,
autoTrack: false, // Don't track until consent
})
<!-- CookieBanner.vue -->
<script setup>
import { useOutlit } from '@outlit/browser/vue'
const { enableTracking, disableTracking, isTrackingEnabled } = useOutlit()
function acceptTracking() {
localStorage.setItem('tracking-consent', 'true')
enableTracking()
}
</script>
<template>
<div v-if="!isTrackingEnabled" class="cookie-banner">
<p>We use cookies to improve your experience.</p>
<div class="flex gap-2">
<button @click="acceptTracking" class="btn-primary">
Accept
</button>
<button @click="disableTracking" class="btn-secondary">
Decline
</button>
</div>
</div>
</template>
Journey Stage Events
Track user progression through your product lifecycle:
<script setup>
import { useOutlit } from '@outlit/browser/vue'
const { user } = useOutlit()
function handleOnboardingComplete() {
user.activate({ flow: 'onboarding', step: 'completed' })
}
function handleFirstProjectCreated() {
user.engaged({ milestone: 'first_project' })
}
</script>
<template>
<button @click="handleOnboardingComplete">
Complete Setup
</button>
</template>
User stage methods (user.activate, user.engaged, user.inactive) require the user to be identified first. Use useOutlitUser(), setUser(), or identify() before calling stage methods.
Account billing status (customer.paid, customer.churned, customer.trialing) is tracked separately at the account level. If you’ve connected Stripe, this is handled automatically.
Vue Router Integration
Track pageviews automatically with Vue Router:
// router/index.ts
import { createRouter, createWebHistory } from 'vue-router'
const router = createRouter({
history: createWebHistory(),
routes: [...]
})
export default router
If you set trackPageviews: true during plugin install (default), pageviews are tracked automatically. Vue Router’s History API changes are detected by the SDK.
Pinia Integration
Track state changes with Pinia:
// stores/user.ts
import { defineStore } from 'pinia'
export const useUserStore = defineStore('user', {
state: () => ({
user: null as User | null
}),
actions: {
async login(email: string, password: string) {
const user = await api.login(email, password)
this.user = user
// Identity is synced automatically via useOutlitUser()
},
logout() {
this.user = null
// Identity is cleared automatically via useOutlitUser()
}
}
})
TypeScript Support
Full TypeScript support is included:
import {
useOutlit,
useTrack,
useIdentify,
useOutlitUser,
OutlitPlugin,
type OutlitPluginOptions,
type UseOutlitReturn,
} from '@outlit/browser/vue'
import type { UserIdentity } from '@outlit/browser'
// Types are inferred
const { track, identify, setUser } = useOutlit()
// User identity type
const user: UserIdentity = {
email: 'user@example.com',
userId: 'usr_123',
traits: { name: 'Jane' }
}
SSR with Nuxt
For Nuxt applications, see the dedicated Nuxt integration guide.
Next Steps