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.
Install
1npm install @avsbhq/browser@^1 @avsbhq/vue@^1Obtain your SDK key
Open Settings > Environments in your A vs B project and copy the SDK key. Expose it via a Vite environment variable:
1VITE_AVSB_SDK_KEY=sdk_production_xxxxxxxxxxxxxxxxRegister 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.
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')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.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.
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>Track an event
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>Identify a user
Use useIdentify after the user authenticates. Calling it replaces the full context and immediately rehashes bucketing.
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:
1import { useAvsbStore } from '@avsbhq/vue'2
3// Setup-style Pinia store exposing client / status / error and4// identify / track / alias actions. Reads the same provider injection5// as useFlag composables.6export const useFlagStore = useAvsbStoreReactive 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:
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
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})