> ## Documentation Index
> Fetch the complete documentation index at: https://docs.outlit.ai/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> Outlit is the product that monitors customers and completes approved customer work. The customer context interfaces are the API, CLI, MCP server, and skills. Canonical references on this site: /api-reference/introduction for API concepts and authentication, /openapi.json for the public API contract, /cli/overview for the CLI, /ai-integrations/mcp for MCP. Prefer the `outlit` CLI or MCP tools for agent tasks; cite page sources when answering.

# Nuxt

> Integrate Outlit tracking with Nuxt 3 applications.

## Installation

<CodeGroup>
  ```bash npm theme={null}
  npm install --save @outlit/browser
  ```

  ```bash pnpm theme={null}
  pnpm add @outlit/browser
  ```

  ```bash yarn theme={null}
  yarn add @outlit/browser
  ```

  ```bash bun theme={null}
  bun add @outlit/browser
  ```
</CodeGroup>

## Quick start

Create a Nuxt plugin to initialize Outlit:

```typescript theme={null}
// plugins/outlit.client.ts
import outlit from '@outlit/browser'

export default defineNuxtPlugin(() => {
  const config = useRuntimeConfig()

  outlit.init({
    publicKey: config.public.outlitKey,
    trackPageviews: true,
  })

  return {
    provide: {
      outlit
    }
  }
})
```

Configure your runtime config:

```typescript theme={null}
// nuxt.config.ts
export default defineNuxtConfig({
  runtimeConfig: {
    public: {
      outlitKey: process.env.NUXT_PUBLIC_OUTLIT_KEY
    }
  }
})
```

Add your public key to `.env`:

```
NUXT_PUBLIC_OUTLIT_KEY=pk_your_public_key_here
```

## Tracking events

Track events using the provided instance:

```vue theme={null}
<script setup>
const { $outlit } = useNuxtApp()

function handleClick() {
  $outlit.track('button_clicked', {
    button: 'cta',
    page: 'pricing'
  })
}
</script>

<template>
  <button @click="handleClick">
    Get Started
  </button>
</template>
```

## Creating a composable

Create a reusable composable for a shorter setup:

```typescript theme={null}
// composables/useOutlit.ts
export function useOutlit() {
  const { $outlit } = useNuxtApp()

  function track(eventName: string, properties?: Record<string, any>) {
    $outlit.track(eventName, properties)
  }

  function identify(options: { email?: string; userId?: string; traits?: Record<string, any> }) {
    $outlit.identify(options)
  }

  function setUser(identity: { email?: string; userId?: string; traits?: Record<string, any> }) {
    $outlit.setUser(identity)
  }

  function clearUser() {
    $outlit.clearUser()
  }

  return {
    track,
    identify,
    setUser,
    clearUser,
    user: $outlit.user,
  }
}
```

Use in components:

```vue theme={null}
<script setup>
const { track } = useOutlit()

function handleFeatureClick() {
  track('feature_used', { feature: 'export' })
}
</script>

<template>
  <button @click="handleFeatureClick">
    Export Data
  </button>
</template>
```

## Identifying users

Identify users after authentication:

```vue theme={null}
<script setup lang="ts">
const { setUser } = useOutlit()
const router = useRouter()

async function handleLogin(email: string, password: string) {
  const user = await $fetch('/api/auth/login', {
    method: 'POST',
    body: { email, password }
  })

  setUser({
    email: user.email,
    userId: user.id,
    traits: {
      name: user.name,
      plan: user.plan
    }
  })

  router.push('/dashboard')
}
</script>
```

## Auth integration

### With Nuxt Auth

```typescript theme={null}
// plugins/outlit.client.ts
import outlit from '@outlit/browser'

export default defineNuxtPlugin(() => {
  const config = useRuntimeConfig()
  const { data: auth } = useAuth()

  outlit.init({
    publicKey: config.public.outlitKey,
    trackPageviews: true,
  })

  // Sync user identity with auth state
  watch(
    () => auth.value,
    (session) => {
      if (session?.user) {
        outlit.setUser({
          email: session.user.email,
          userId: session.user.id,
          traits: {
            name: session.user.name
          }
        })
      } else {
        outlit.clearUser()
      }
    },
    { immediate: true }
  )

  return {
    provide: { outlit }
  }
})
```

### With Supabase

```typescript theme={null}
// plugins/outlit.client.ts
import outlit from '@outlit/browser'

export default defineNuxtPlugin(async () => {
  const config = useRuntimeConfig()
  const supabase = useSupabaseClient()
  const user = useSupabaseUser()

  outlit.init({
    publicKey: config.public.outlitKey,
    trackPageviews: true,
  })

  // Sync user identity
  watch(
    user,
    (currentUser) => {
      if (currentUser) {
        outlit.setUser({
          email: currentUser.email!,
          userId: currentUser.id,
          traits: {
            name: currentUser.user_metadata?.name
          }
        })
      } else {
        outlit.clearUser()
      }
    },
    { immediate: true }
  )

  return {
    provide: { outlit }
  }
})
```

## Router integration

Track route changes:

```typescript theme={null}
// plugins/outlit.client.ts
import outlit from '@outlit/browser'

export default defineNuxtPlugin(() => {
  const config = useRuntimeConfig()
  const router = useRouter()

  outlit.init({
    publicKey: config.public.outlitKey,
    trackPageviews: false, // Manual pageview tracking
  })

  // Track pageviews on route change
  router.afterEach((to) => {
    outlit.track('pageview', {
      path: to.path,
      name: to.name,
      params: to.params,
      query: to.query
    })
  })

  return {
    provide: { outlit }
  }
})
```

## Server-side tracking

Track events from server API routes:

```typescript theme={null}
// server/api/checkout.post.ts
import { Outlit } from '@outlit/node'

const outlit = new Outlit({
  publicKey: process.env.OUTLIT_KEY!
})

export default defineEventHandler(async (event) => {
  const body = await readBody(event)

  outlit.track({
    userId: body.userId,
    eventName: 'checkout_completed',
    properties: {
      amount: body.amount,
      plan: body.plan
    }
  })

  await outlit.flush()

  return { success: true }
})
```

For server-side tracking, see the [Node.js integration guide](/tracking/server/nodejs).

## Activation event

Track your value milestone as an ordinary event once it succeeds:

```vue theme={null}
<script setup>
const { track } = useOutlit()

function handleOnboardingComplete() {
  track('onboarding_completed', { flow: 'onboarding', step: 'completed' })
}
</script>
```

Choose this event as your activation event in Outlit. The first matching event records activation once for each eligible resolved person and company, independently. Billing status comes from verified integrations such as Stripe. See [Customer journey](/concepts/customer-journey).

## Consent management

The default `autoTrack: "auto"` mode already keeps tracking off for visitors in regions that require opt-in consent (EEA, UK, Switzerland, or unknown); the example below uses `autoTrack: false` to wait for an explicit consent signal unless a previous opt-in is stored.

Handle user consent:

```vue theme={null}
<script setup>
const showBanner = ref(false)
const { $outlit } = useNuxtApp()

onMounted(() => {
  const hasConsent = localStorage.getItem('tracking-consent')
  if (hasConsent !== 'true') {
    showBanner.value = true
  }
})

function acceptTracking() {
  localStorage.setItem('tracking-consent', 'true')
  $outlit.enableTracking()
  showBanner.value = false
}
</script>

<template>
  <div v-if="showBanner" class="cookie-banner">
    <p>We use cookies to improve your experience.</p>
    <button @click="acceptTracking">Accept</button>
  </div>
</template>
```

Initialize without auto-tracking:

```typescript theme={null}
// plugins/outlit.client.ts
import outlit from '@outlit/browser'

export default defineNuxtPlugin(() => {
  const config = useRuntimeConfig()

  outlit.init({
    publicKey: config.public.outlitKey,
    autoTrack: false, // Wait for consent
  })

  return {
    provide: { outlit }
  }
})
```

## Environment variables

Configure environment variables:

```bash theme={null}
# .env

# Public key (used in browser)
NUXT_PUBLIC_OUTLIT_KEY=pk_your_public_key_here

# Server key (used in server API routes)
OUTLIT_KEY=pk_your_public_key_here
```

<Warning>
  Keep server environment variables out of client-side code. Only use `OUTLIT_KEY` in server API routes.
</Warning>

## TypeScript support

Full TypeScript support is included:

```typescript theme={null}
// plugins/outlit.client.ts
import outlit, { type OutlitOptions } from '@outlit/browser'

export default defineNuxtPlugin(() => {
  const config = useRuntimeConfig()

  const options: OutlitOptions = {
    publicKey: config.public.outlitKey,
    trackPageviews: true,
    flushInterval: 5000
  }

  outlit.init(options)

  return {
    provide: { outlit }
  }
})
```

## Next steps

<CardGroup cols={2}>
  <Card title="Vue integration" icon="vuejs" href="/tracking/browser/vue">
    Use Outlit with Vue 3
  </Card>

  <Card title="Server-side tracking" icon="server" href="/tracking/server/nodejs">
    Track events from your backend
  </Card>

  <Card title="Identity resolution" icon="fingerprint" href="/concepts/identity-resolution">
    Learn how visits and events link to people
  </Card>

  <Card title="npm package" icon="npm" href="/tracking/browser/npm">
    Full API reference
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.