Vue SDK (beta)
Vue client side library for Reflag.com
Reflag supports flag toggling, tracking flag usage, requesting feedback on features and remotely configuring flags.
The Reflag Vue SDK comes with the same built-in toolbar as the browser SDK which appears on localhost by default.
Install
Install via npm:
npm i @reflag/vue-sdkMigrating from Bucket SDK
If you have been using the Bucket SDKs, the following list will help you migrate to Reflag SDK:
Bucket*classes, and types have been renamed toReflag*(e.g.BucketClientis nowReflagClient)Feature*classes, and types have been renamed toFeature*(e.g.Featureis nowFlag,RawFeaturesis nowRawFlags)All methods that contained
featurein the name have been renamed to use theflagterminology (e.g.getFeatureisgetFlag)The
fallbackFeaturesproperty in client constructor and configuration files has been renamed tofallbackFlagsfeatureKeyhas been renamed toflagKeyin all methods that accepts that argumentThe SDKs will not emit
evaluateandevaluate-configevents anymoreThe new cookies that are stored in the client's browser are now
reflag-*prefixed instead ogbucket-*The
featuresUpdatedhook has been renamed toflagsUpdatedThe
checkIsEnabledandcheckConfighooks have been removed, usecheckfrom now on
To ease in transition to Reflag SDK, some of the old methods have been preserved as aliases to the new methods:
getFeaturemethod is an alias forgetFlaggetFeaturesmethod is an alias forgetFlagsfeaturesUpdatedhook is an alias forflagsUpdated
If you are running with strict Content Security Policies active on your website, you will need change them as follows:
connect-src https://front.bucket.cotoconnect-src https://front.reflag.com
Finally, if you have customized the look & feel of the Feedback component, update --bucket-feedback-* CSS classes to --reflag-feedback-*
Get started
1. Add the ReflagProvider context provider
ReflagProvider context providerAdd the ReflagProvider context provider to your application:
Example:
<script setup lang="ts">
import { ReflagProvider } from "@reflag/vue-sdk";
</script>
<ReflagProvider
:publishable-key="publishableKey"
:context="{
user: { id: 'user_123', name: 'John Doe', email: '[email protected]' },
company: { id: 'acme_inc', plan: 'pro' },
}"
>
<!-- your app -->
</ReflagProvider>If using Nuxt, wrap <ReflagProvider> in <ClientOnly>. <ReflagProvider> only renders client-side currently.
2. Use `useFlag get flag status
<script setup lang="ts">
import { useFlag } from "@reflag/vue-sdk";
const { isEnabled } = useFlag("huddles");
</script>
<template>
<div v-if="isEnabled">
<button>Start huddles!</button>
</div>
</template>See useFlag() for a full example
Setting context
Reflag determines which flags are active for a given user, company, or other context. You can pass these to the ReflagProvider using the context prop.
Using the context prop
context prop<ReflagProvider
:publishable-key="publishableKey"
:context="{
user: { id: 'user_123', name: 'John Doe', email: '[email protected]' },
company: { id: 'acme_inc', plan: 'pro' },
other: { source: 'web' },
}"
>
<!-- your app -->
</ReflagProvider>Legacy individual props (deprecated)
For backward compatibility, you can still use individual props, but these are deprecated and will be removed in the next major version:
<ReflagProvider
:publishable-key="publishableKey"
:user="{ id: 'user_123', name: 'John Doe', email: '[email protected]' }"
:company="{ id: 'acme_inc', plan: 'pro' }"
:other-context="{ source: 'web' }"
>
<!-- your app -->
</ReflagProvider>[!Important] The
user,company, andotherContextprops are deprecated. Use thecontextprop instead, which provides the same functionality in a more structured way.
Context requirements
If you supply user or company objects, they must include at least the id property otherwise they will be ignored in their entirety. In addition to the id, you must also supply anything additional that you want to be able to evaluate flag targeting rules against. Attributes which are not properties of the user or company can be supplied using the other property.
Attributes cannot be nested (multiple levels) and must be either strings, numbers or booleans. A number of special attributes exist:
name-- display name foruser/company,email-- the email of the user,avatar-- the URL foruser/companyavatar image.
To retrieve flags along with their targeting information, use useFlag(key: string) hook (described in a section below).
Note that accessing isEnabled on the object returned by useFlag() automatically generates a check event.
Remote config
Remote config is a dynamic and flexible approach to configuring flag behavior outside of your app – without needing to re-deploy it.
Similar to isEnabled, each flag accessed using the useFlag() hook, has a config property. This configuration is managed from within Reflag. It is managed similar to the way access to flags is managed, but instead of the binary isEnabled you can have multiple configuration values which are given to different user/companies.
Get started with Remote config
const {
isEnabled,
config: { key, payload },
} = useFlag("huddles");
// isEnabled: true,
// key: "gpt-3.5",
// payload: { maxTokens: 10000, model: "gpt-3.5-beta1" }key is mandatory for a config, but if a flag has no config or no config value was matched against the context, the key will be undefined. Make sure to check against this case when trying to use the configuration in your application. payload is an optional JSON value for arbitrary configuration needs.
Note that, similar to isEnabled, accessing config on the object returned by useFlag() automatically generates a check event.
<ReflagProvider> component
<ReflagProvider> componentThe <ReflagProvider> initializes the Reflag SDK, fetches flags and starts listening for automated feedback survey events. The component can be configured using a number of props:
publishableKeyis used to connect the provider to an environment on Reflag. Find yourpublishableKeyunder environment settings in Reflag,context: An object containinguser,company, andotherproperties that make up the evaluation context used to determine if a flag is enabled or not.companyandusercontexts are automatically transmitted to Reflag servers so the Reflag app can show you which companies have access to which flags etc.company,userandotherContext(deprecated): Individual props for context. These are deprecated in favor of thecontextprop and will be removed in the next major version.[!Note] If you specify
companyand/oruserthey must have at least theidproperty, otherwise they will be ignored in their entirety. You should also supply anything additional you want to be able to evaluate flag targeting against,timeoutMs: Timeout in milliseconds when fetching flags from the server,staleWhileRevalidate: If set totrue, stale flags will be returned while refetching flags in the background,expireTimeMs: If set, flags will be cached between page loads for this duration (in milliseconds),staleTimeMs: Maximum time (in milliseconds) that stale flags will be returned ifstaleWhileRevalidateis true and new flags cannot be fetched.enableTracking: Set tofalseto stop sending tracking events and user/company updates to Reflag. Useful when you're impersonating a user (defaults totrue),apiBaseUrl: Optional base URL for the Reflag API. Use this to override the default API endpoint,appBaseUrl: Optional base URL for the Reflag application. Use this to override the default app URL,sseBaseUrl: Optional base URL for Server-Sent Events. Use this to override the default SSE endpoint,debug: Set totrueto enable debug logging to the console,toolbar: Optional configuration for the Reflag toolbar,feedback: Optional configuration for feedback collection
Loading states
ReflagProvider lets you define a template to be shown while ReflagProvider is initializing:
<template>
<ReflagProvider
:publishable-key="publishableKey"
:user="user"
:company="{ id: 'acme_inc', plan: 'pro' }"
>
<template #loading>Loading...</template>
<StartHuddlesButton />
</ReflagProvider>
</template>If you want more control over loading screens, useIsLoading() returns a Ref<boolean> which you can use to customize the loading experience.
<ReflagBootstrappedProvider> component
<ReflagBootstrappedProvider> componentThe <ReflagBootstrappedProvider> component is a specialized version of ReflagProvider designed for server-side rendering and preloaded flag scenarios. Instead of fetching flags on initialization, it uses pre-fetched flags, resulting in faster initial page loads and better SSR compatibility.
Usage
<script setup lang="ts">
import { ReflagBootstrappedProvider } from "@reflag/vue-sdk";
// Pre-fetched flags (typically from your server/SSR layer)
const bootstrappedFlags = {
context: {
user: { id: "user123", name: "John Doe", email: "[email protected]" },
company: { id: "company456", name: "Acme Inc", plan: "enterprise" },
},
flags: {
huddles: {
isEnabled: true,
config: {
key: "enhanced",
payload: { maxParticipants: 50, videoQuality: "hd" },
},
},
},
};
</script>
<template>
<ReflagBootstrappedProvider
:publishable-key="publishableKey"
:flags="bootstrappedFlags"
>
<StartHuddlesButton />
</ReflagBootstrappedProvider>
</template>Getting bootstrapped flags
You'll typically generate the bootstrappedFlags object on your server using the Node.js SDK or by fetching from the Reflag API. Here's an example using the Node.js SDK:
// server.js (Node.js/SSR)
import { ReflagClient } from "@reflag/node-sdk";
const client = new ReflagClient({
secretKey: "your-secret-key", // Use secret key on server
});
await client.initialize();
// Fetch flags for specific context
const context = {
user: { id: "user123", name: "John Doe", email: "[email protected]" },
company: { id: "company456", name: "Acme Inc", plan: "enterprise" },
};
const bootstrappedFlags = client.getFlagsForBootstrap(context);
// Pass to your Vue appReflagBootstrappedProvider Props
ReflagBootstrappedProvider accepts all the same props as ReflagProvider except:
flags: The pre-fetched flags object containing context and flag dataAll other props available in
ReflagProviderare supported exceptcontext,user,company, andotherContext(which are extracted fromflags.context)
If the flags prop is not provided or is undefined, the provider will not initialize the client and will render in a non-loading state.
<ReflagClientProvider> component
<ReflagClientProvider> componentThe <ReflagClientProvider> is a lower-level component that accepts a pre-initialized ReflagClient instance. This is useful for advanced use cases where you need full control over client initialization or want to share a client instance across multiple parts of your application.
ReflagClientProvider Usage
<script setup lang="ts">
import { ReflagClient } from "@reflag/browser-sdk";
import { ReflagClientProvider } from "@reflag/vue-sdk";
// Initialize the client yourself
const client = new ReflagClient({
publishableKey: "your-publishable-key",
user: { id: "user123", name: "John Doe" },
company: { id: "company456", name: "Acme Inc" },
// ... other configuration options
});
// Initialize the client
await client.initialize();
</script>
<template>
<ReflagClientProvider :client="client">
<template #loading>Loading...</template>
<Router />
</ReflagClientProvider>
</template>ReflagClientProvider Props
The ReflagClientProvider accepts the following props:
client: A pre-initializedReflagClientinstance
Slots
loading: Optional slot to show while the client is initializing (same asReflagProvider)
[!Note] Most applications should use
ReflagProviderorReflagBootstrappedProviderinstead ofReflagClientProvider. Only use this component when you need the advanced control it provides.
Hooks
useFlag()
useFlag()Returns the state of a given flag for the current context. The composable provides access to flags and their configurations.
useFlag() returns an object with this shape:
{
isEnabled: boolean, // is the flag enabled
track: () => void, // send a track event when the flag is used
requestFeedback: (...) => void // open up a feedback dialog
config: {key: string, payload: any}, // remote configuration for this flag
isLoading: boolean // if you want to manage loading state at the flag level
}Example:
<script setup lang="ts">
import { useFlag } from "@reflag/vue-sdk";
const { isEnabled, track, requestFeedback, config } = useFlag("huddles");
</script>
<template>
<div v-if="isLoading">Loading...</div>
<div v-else-if="!isEnabled">Flag not available</div>
<div v-else>
<button @click="track()">Start huddles!</button>
<button
@click="
(e) =>
requestFeedback({
title:
config.payload?.question ??
'How do you like the Huddles feature?',
position: {
type: 'POPOVER',
anchor: e.currentTarget as HTMLElement,
},
})
"
>
Give feedback!
</button>
</div>
</template>See the reference docs for details.
useTrack()
useTrack()useTrack() returns a function which lets you send custom events to Reflag. It takes a string argument with the event name and optionally an object with properties to attach the event.
Using track returned from useFlag() calls this track function with the flag key as the event name.
<script setup lang="ts">
import { useTrack } from "@reflag/vue-sdk";
const track = useTrack();
</script>
<template>
<div>
<button @click="track('Huddles Started', { huddlesType: 'voice' })">
Start voice huddles!
</button>
</div>
</template>useRequestFeedback()
useRequestFeedback()Returns a function that lets you open up a dialog to ask for feedback on a specific feature. This is useful for collecting targeted feedback about specific features.
See Automated Feedback Surveys for how to do this automatically, without code.
When using the useRequestFeedback you must pass the flag key to requestFeedback. The example below shows how to use position to ensure the popover appears next to the "Give feedback!" button.
<script setup lang="ts">
import { useRequestFeedback } from "@reflag/vue-sdk";
const requestFeedback = useRequestFeedback();
</script>
<template>
<button
@click="
(e) =>
requestFeedback({
flagKey: 'huddles',
title: 'How satisfied are you with file uploads?',
position: {
type: 'POPOVER',
anchor: e.currentTarget as HTMLElement,
},
// Optional custom styling
style: {
theme: 'light',
primaryColor: '#007AFF',
},
})
"
>
Give feedback!
</button>
</template>See the Feedback Documentation for more information on requestFeedback options.
useSendFeedback()
useSendFeedback()Returns a function that lets you send feedback to Reflag. This is useful if you've manually collected feedback through your own UI and want to send it to Reflag.
<script setup lang="ts">
import { useSendFeedback } from "@reflag/vue-sdk";
const sendFeedback = useSendFeedback();
const handleSubmit = async (data: FormData) => {
await sendFeedback({
flagKey: "reflag-flag-key",
score: parseInt(data.get("score") as string),
comment: data.get("comment") as string,
});
};
</script>
<template>
<form @submit="handleSubmit">
<!-- form content -->
</form>
</template>useUpdateUser(), useUpdateCompany() and useUpdateOtherContext()
useUpdateUser(), useUpdateCompany() and useUpdateOtherContext()These composables return functions that let you update the attributes for the currently set user, company, or other context. Updates to user/company are stored remotely and affect flag targeting, while "other" context updates only affect the current session.
<script setup lang="ts">
import {
useUpdateUser,
useUpdateCompany,
useUpdateOtherContext,
} from "@reflag/vue-sdk";
const updateUser = useUpdateUser();
const updateCompany = useUpdateCompany();
const updateOtherContext = useUpdateOtherContext();
const handleUserUpdate = async () => {
await updateUser({
role: "admin",
betaFeatures: "enabled",
});
};
const handleCompanyUpdate = async () => {
await updateCompany({
plan: "enterprise",
employees: 500,
});
};
const handleContextUpdate = async () => {
await updateOtherContext({
currentWorkspace: "workspace-123",
theme: "dark",
});
};
</script>
<template>
<div>
<button @click="handleUserUpdate">Update User</button>
<button @click="handleCompanyUpdate">Update Company</button>
<button @click="handleContextUpdate">Update Context</button>
</div>
</template>Note: To change the user.id or company.id, you need to update the props passed to ReflagProvider instead of using these composables.
useClient()
useClient()Returns the ReflagClient used by the ReflagProvider. The client offers more functionality that is not directly accessible through the other composables.
<script setup>
import { useClient } from "@reflag/vue-sdk";
import { onMounted } from "vue";
const client = useClient();
console.log(client.getContext());
</script>
<template>
<!-- your component content -->
</template>useIsLoading()
useIsLoading()Returns a Ref<boolean> to indicate if Reflag has finished loading. Initially, the value will be true if no bootstrap flags have been provided and the client has not be initialized.
<script setup>
import { useIsLoading } from "@reflag/vue-sdk";
import { Spinner } from "./Spinner";
const isLoading = useIsLoading();
</script>
<template>
<!-- your component content -->
</template>useOnEvent()
useOnEvent()Vue composable for listening to Reflag client events. This composable automatically handles mounting and unmounting of event listeners.
Available events include:
flagsUpdated: Triggered when flags are updatedtrack: Triggered when tracking events are sentfeedback: Triggered when feedback is sent
<script setup lang="ts">
import { useOnEvent } from "@reflag/vue-sdk";
// Listen to flag updates
useOnEvent("flagsUpdated", () => {
console.log("Flags have been updated");
});
</script>
<template>
<!-- your component content -->
</template>You can also provide a specific client instance if needed:
<script setup lang="ts">
import { ReflagClient } from "@reflag/browser-sdk";
const myReflagClient = new ReflagClient();
useOnEvent(
"flagsUpdated",
() => {
console.log("flags updated");
},
myReflagClient,
);
</script>
<template>
<!-- your component content -->
</template>Content Security Policy (CSP)
See CSP for info on using Reflag React SDK with CSP
License
MIT License
Copyright (c) 2025 Bucket ApS
Last updated
Was this helpful?