# Vue SDK (/docs/sdk/vue)

The Vue SDK sits around the [Javascript Client SDK](/docs/sdk/javascript#client) and gives Vue 3 and Nuxt a provider and composables.

## Install [#install]

```bash
npm i @obelism/improve-sdk-vue
```

## Setup [#setup]

Generate the provider and composables once, and export them:

```ts title="improve.ts"
import { generateImproveProvider } from '@obelism/improve-sdk-vue'

export const {
	ImproveProvider,
	useImproveStatus,
	usePostAnalytic,
	useTestValue,
	useFlagValue,
} = generateImproveProvider(...)
```

## API [#api]

### generateImproveProvider [#generateimproveprovider]

```ts
generateImproveProvider(improveArgs: ImproveSetupArgs) => ({
    ImproveProvider,
    useImproveStatus,
    usePostAnalytic,
    useTestValue,
    useFlagValue
})
```

Setup function that generates the provider component and the composables. The argument is the same [`ImproveSetupArgs`](/docs/sdk/javascript#types) used by the Client SDK (`organizationId`, `environment`, optional `config`, `fetchTimeout`, `baseUrl`, `dataLayer`, …). Each call has its own provider, so two spaces on one page never mix.

### ImproveProvider [#improveprovider]

```vue
<ImproveProvider>
	<NuxtPage />
</ImproveProvider>
```

After mount it loads the client SDK, and the config unless one was given. The server and hydration render the fallbacks, so the markup matches. The composables read the provider above them: call them in components inside it, not in the component that renders it.

### useImproveStatus [#useimprovestatus]

```ts
const status: ComputedRef<'loading' | 'setup' | 'error'> = useImproveStatus()
```

Where the provider is in its lifecycle: `loading` while the SDK and config are being fetched, `setup` once it's ready, or `error` if setup failed.

### useFlagValue [#useflagvalue]

```ts
const value: ComputedRef<string | undefined> = useFlagValue(flagSlug: string, fallback?: string)
```

Wrapper around [getFlagValue](/docs/sdk/javascript#getflagvalue). Gives `fallback` while the config is still loading or when no flag matches the slug.

### useTestValue [#usetestvalue]

```ts
const value: ComputedRef<string | undefined> = useTestValue(testSlug: string, fallback?: string)
```

Wrapper around [getTestValue](/docs/sdk/javascript#gettestvalue). Gives `fallback` while the config is still loading or when no test matches the slug. Reading the value once the SDK is set up records the visitor's **exposure**, which events are attributed to.

### usePostAnalytic [#usepostanalytic]

`usePostAnalytic` takes no arguments and returns a global `postAnalytic` function. Events are **test-independent**: call the returned function with an event name, a required `scope` (a short, stable identifier for where/what the event refers to, not display text), and an optional payload, and the server attributes the event to whichever tests/flags the visitor was exposed to. It does nothing until the SDK is set up.

```vue
<script setup lang="ts">
const postAnalytic = usePostAnalytic()
</script>

<template>
	<!-- Simple event -->
	<button @click="postAnalytic('add_to_cart', 'product_page')">Add</button>

	<!-- With a value for revenue / AOV, and GA4 ecommerce params for GTM -->
	<button
		@click="
			postAnalytic('purchase', 'checkout', {
				value: 72.05,
				currency: 'USD',
				params: { ecommerce: { transaction_id: 'T_1', items: [] } },
			})
		"
	>
		Buy
	</button>
</template>
```

Wrapper around [postAnalytic](/docs/sdk/javascript#postanalytic).

## Nuxt [#nuxt]

The provider only loads the SDK in the browser, so it works in `app.vue` as is. To decide a test on the server instead, before the first paint, add the [Nuxt SDK](/docs/sdk/nuxt).
