Skip to main content

Installation

npm install --save @outlit/browser

Quick Start

Install the OutlitPlugin in your app’s entry point and use composables in components.
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

publicKey
string
required
Your organization’s public key.
apiHost
string
default:"https://app.outlit.ai"
API endpoint for sending events.
trackPageviews
boolean
default:"true"
Automatically track pageviews on route changes.
trackForms
boolean
default:"true"
Automatically capture form submissions.
formFieldDenylist
string[]
Additional field names to exclude from form capture.
flushInterval
number
default:"5000"
How often to flush queued events (ms).
autoTrack
boolean
default:"true"
Whether to start tracking automatically. Set to false to wait for user consent. Use enableTracking() from the useOutlit composable after consent.
autoIdentify
boolean
default:"true"
Automatically identify users when they submit forms containing an email field. Set to false to disable and call identify() manually.
trackEngagement
boolean
default:"true"
Track engagement metrics (active time on page).
idleTimeout
number
default:"30000"
Idle timeout in milliseconds for engagement tracking.
trackCalendarEmbeds
boolean
default:"true"
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.
clearUser
() => void
Clear the current user identity (on logout).
user
object
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
object
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
getVisitorId
() => string | null
Get the current visitor’s ID. Returns null if tracking is not enabled.
isTrackingEnabled
Ref<boolean>
Whether tracking is currently enabled. Will be false if autoTrack is false and enableTracking() hasn’t been called.
enableTracking
() => void
Enable tracking. Call this after obtaining user consent. Only needed if autoTrack is false.
disableTracking
() => void
Disable tracking and flush any pending events. Use this when a user declines or revokes consent.
isInitialized
Ref<boolean>
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>
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