/Docs

Vite + Vue 3 integration

This guide assumes a Vite project using Vue 3.4 or later as a single-page application with the Composition API. By the end you'll have reactive flag evaluation and event tracking using @avsbhq/browser and @avsbhq/vue.

1

Install

bash
1npm install @avsbhq/browser@^1 @avsbhq/vue@^1
2

Obtain your SDK key

Open Settings > Environments in your A vs B project and copy the SDK key. Expose it via a Vite environment variable:

.env
bash
1VITE_AVSB_SDK_KEY=sdk_production_xxxxxxxxxxxxxxxx
3

Register the plugin in main.ts

@avsbhq/vue ships as a Vue plugin. Call app.use(AvsbPlugin, { sdkKey, context }) before mounting. The plugin provides the client to the entire component tree.

src/main.ts
ts
1import { createApp } from 'vue'
2import { AvsbPlugin } from '@avsbhq/vue'
3import App from './App.vue'
4
5const app = createApp(App)
6
7app.use(AvsbPlugin, {
8 sdkKey: import.meta.env.VITE_AVSB_SDK_KEY,
9 context: { kind: 'user', key: 'anonymous' },
10})
11
12app.mount('#app')
Tip
Alternatively you can mount the AvsbProvider SFC at the root of your component tree instead of using the plugin. Both approaches are equivalent; the plugin is the recommended pattern for Vite projects.
4

Read a flag

Use the useFlag composable inside any component. It returns a reactive ComputedRef<Flag<T>> that updates automatically when the flag value changes.

src/components/CheckoutSection.vue
vue
1<script setup lang="ts">
2import { useFlag } from '@avsbhq/vue'
3
4const checkoutV2 = useFlag('checkout-v2', false)
5</script>
6
7<template>
8 <NewCheckout v-if="checkoutV2.value" />
9 <LegacyCheckout v-else />
10</template>
5

Track an event

src/components/PurchaseButton.vue
vue
1<script setup lang="ts">
2import { useTrack } from '@avsbhq/vue'
3
4const track = useTrack()
5
6function handlePurchase() {
7 track('purchase', { value: 49.99, properties: { plan: 'pro' } })
8}
9</script>
10
11<template>
12 <button type="button" @click="handlePurchase">Buy now</button>
13</template>
6

Identify a user

Use useIdentify after the user authenticates. Calling it replaces the full context and immediately rehashes bucketing.

vue
1<script setup lang="ts">
2import { useIdentify } from '@avsbhq/vue'
3
4const identify = useIdentify()
5
6// Call once after login resolves.
7function onLogin(userId: string, plan: string) {
8 identify({ kind: 'user', key: userId, plan })
9}
10</script>

Optional Pinia integration

If your project uses Pinia, @avsbhq/vue ships an optional Pinia store that mirrors flag state into the store for DevTools inspection:

src/stores/flags.ts
ts
1import { useAvsbStore } from '@avsbhq/vue'
2
3// Setup-style Pinia store exposing client / status / error and
4// identify / track / alias actions. Reads the same provider injection
5// as useFlag composables.
6export const useFlagStore = useAvsbStore

Reactive streams

For advanced use cases, useFlag wraps the underlying client subscription. You can also use useAllFlags to get a reactive map of every flag in a single computed:

ts
1import { useAllFlags } from '@avsbhq/vue'
2
3const allFlags = useAllFlags()
4// Reactive Record<string, Flag<unknown>>. Updates on every flag change.

Graceful shutdown

The plugin calls client.close() automatically in the app.unmount() lifecycle. In a Vite SPA, this happens automatically during development HMR teardown and on browser tab close (via visibilitychange + beforeunload).

Testing

ts
1import { createMockClient, TestData } from '@avsbhq/test'
2import { mount } from '@vue/test-utils'
3import { AvsbPlugin } from '@avsbhq/vue'
4import CheckoutSection from './CheckoutSection.vue'
5
6const td = TestData.flag('checkout-v2').booleanFlag().fallthroughVariation(true)
7const client = createMockClient({ flags: [td.build()] })
8
9mount(CheckoutSection, {
10 global: { plugins: [[AvsbPlugin, { client }]] },
11})

What's next