# Reflag Vue SDK (beta) Vue client side library for [Reflag.com](https://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: ```shell npm i @reflag/vue-sdk ``` ## Migrating 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 to `Reflag*` (e.g. `BucketClient` is now `ReflagClient`) - `Feature*` classes, and types have been renamed to `Feature*` (e.g. `Feature` is now `Flag`, `RawFeatures` is now `RawFlags`) - All methods that contained `feature` in the name have been renamed to use the `flag` terminology (e.g. `getFeature` is `getFlag`) - The `fallbackFeatures` property in client constructor and configuration files has been renamed to `fallbackFlags` - `featureKey` has been renamed to `flagKey` in all methods that accepts that argument - The SDKs will not emit `evaluate` and `evaluate-config` events anymore - The new cookies that are stored in the client's browser are now `reflag-*` prefixed instead og `bucket-*` - The `featuresUpdated` hook has been renamed to `flagsUpdated` - The `checkIsEnabled` and `checkConfig` hooks have been removed, use `check` from now on To ease in transition to Reflag SDK, some of the old methods have been preserved as aliases to the new methods: - `getFeature` method is an alias for `getFlag` - `getFeatures` method is an alias for `getFlags` - `featuresUpdated` hook is an alias for `flagsUpdated` 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.co` to `connect-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 Add the `ReflagProvider` context provider to your application: **Example:** ```vue ``` If using Nuxt, wrap `` in ``. `` only renders client-side currently. ### 2. Use `useFlag get flag status ```vue ``` See [useFlag()](#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 ```vue ``` ### 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: ```vue ``` > [!Important] > The `user`, `company`, and `otherContext` props are deprecated. Use the `context` prop 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 for `user`/`company`, - `email` -- the email of the user, - `avatar` -- the URL for `user`/`company` avatar 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 ```ts 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. ## `` component The `` initializes the Reflag SDK, fetches flags and starts listening for automated feedback survey events. The component can be configured using a number of props: - `publishableKey` is used to connect the provider to an _environment_ on Reflag. Find your `publishableKey` under [environment settings](https://app.reflag.com/env-current/settings/app-environments) in Reflag, - `context`: An object containing `user`, `company`, and `other` properties that make up the evaluation context used to determine if a flag is enabled or not. `company` and `user` contexts are automatically transmitted to Reflag servers so the Reflag app can show you which companies have access to which flags etc. - `company`, `user` and `otherContext` (deprecated): Individual props for context. These are deprecated in favor of the `context` prop and will be removed in the next major version. > [!Note] > If you specify `company` and/or `user` they must have at least the `id` property, 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 to `true`, 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 if `staleWhileRevalidate` is true and new flags cannot be fetched. - `enableTracking`: Set to `false` to stop sending tracking events and user/company updates to Reflag. Useful when you're impersonating a user (defaults to `true`), - `apiBaseUrl`: Optional base URL for the Reflag API. This also controls the SSE origin used for live flag updates and automated feedback, - `credentials`: Optional fetch credentials mode. Set to `"include"` when proxying through your backend and authenticating with cookies; this also enables credentials for live-update SSE connections. - `appBaseUrl`: Optional base URL for the Reflag application. Use this to override the default app URL, - `debug`: Set to `true` to enable debug logging to the console. If both `logger` and `debug` are provided, `logger` takes precedence, - `logger`: Optional custom logger implementation (`debug`, `info`, `warn`, `error`) used by the underlying client, - `toolbar`: Optional [configuration](https://docs.reflag.com/supported-languages/browser-sdk/globals#toolbaroptions) 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: ```vue ``` If you want more control over loading screens, `useIsLoading()` returns a `Ref` which you can use to customize the loading experience. ## `` component The `` component is a specialized version of `ReflagProvider` designed for server-side rendering and preloaded flag scenarios. It uses pre-fetched flags for the initial render, resulting in faster initial page loads and better SSR compatibility. ### Usage ```vue ``` ### 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. Pass the full object returned by `getFlagsForBootstrap()` directly to ``. It contains: - `context`: the evaluation context used on the server - `flags`: the evaluated raw flags - `flagStateVersion`: an optional version used to avoid redundant live-update refreshes immediately after bootstrapping If you want live flag updates to continue working after bootstrapping, use a recent `@reflag/node-sdk` so `getFlagsForBootstrap()` includes `flagStateVersion`. With `ReflagBootstrappedProvider`, `useOptInFlags()` triggers one flags refresh and reports `isLoading: true` until it settles. No refresh occurs unless the composable is used. Here's an example using the Node.js SDK: ```js // 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: "john@acme.com" }, company: { id: "company456", name: "Acme Inc", plan: "enterprise" }, }; const bootstrappedFlags = client.getFlagsForBootstrap(context); // Pass to your Vue app ``` ### ReflagBootstrappedProvider Props `ReflagBootstrappedProvider` accepts all the same props as `ReflagProvider` except: - `flags`: The pre-fetched bootstrapped state object containing `context`, evaluated `flags`, and an optional `flagStateVersion` - All other props available in `ReflagProvider` are supported except `context`, `user`, `company`, and `otherContext` (which are extracted from `flags.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. > [!NOTE] > The on-demand browser refresh and any later live flag updates use the browser-visible context. If your bootstrapped snapshot depends on server-only or secret context that is not available in the browser, refreshed flags may differ. In that case, keep `enableLiveFlagUpdates` disabled. ## `` component The `` 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 ```vue ``` ### ReflagClientProvider Props The `ReflagClientProvider` accepts the following props: - `client`: A pre-initialized `ReflagClient` instance ### Slots - `loading`: Optional slot to show while the client is initializing (same as `ReflagProvider`) > [!Note] > Most applications should use `ReflagProvider` or `ReflagBootstrappedProvider` instead of `ReflagClientProvider`. Only use this component when you need the advanced control it provides. ## Hooks ### `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: ```ts { 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: ```vue ``` See the reference docs for details. ### `useOptInFlags()` and `useSetOptIn()` Use these composables to build an end-user opt-in UI for flags where opt-in is enabled in Reflag. ```vue ``` By default, `useSetOptIn()` changes the opt-in for the current user, so the current context must include a `user.id`. To manage the current company's opt-in instead, pass `scope: "company"`; the context must then include a `company.id`. User and company opt-ins are managed independently. Setting `optedIn` to `false` removes the opt-in only for the selected scope. For example, cancelling a user's opt-in does not change the company's opt-in for the same flag. `setOptIn` returns a promise so you can wait for the new membership state to be synchronized. It resolves after the latest flag state has been applied, the requested membership change has been confirmed, and components using `useOptInFlags()` have been notified. Vue schedules the resulting render normally, so it may not yet be committed when the promise resolves. `useOptInFlags()` returns `{ flags, isLoading }`, where both values are computed refs. With `ReflagBootstrappedProvider`, the composable fetches opt-in metadata on first use and reports `isLoading: true` until the flags refresh succeeds or fails. With a regular `ReflagProvider`, opt-in metadata arrives as part of the normal initial flags request, so `useOptInFlags().isLoading` remains `false`. Use the general `useIsLoading()` composable or the provider's loading slot for that initial loading state. ### `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. ```vue ``` ### `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](https://docs.reflag.com/product-handbook/live-satisfaction) 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. ```vue ``` See the [Feedback Documentation](https://github.com/reflagcom/javascript/blob/main/packages/browser-sdk/FEEDBACK.md#manual-feedback-collection) for more information on `requestFeedback` options. ### `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. ```vue ``` ### `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. ```vue ``` Note: To change the `user.id` or `company.id`, you need to update the props passed to `ReflagProvider` instead of using these composables. ### `useClient()` Returns the `ReflagClient` used by the `ReflagProvider`. The client offers more functionality that is not directly accessible through the other composables. ```vue ``` ### `useIsLoading()` Returns a `Ref` 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. ```vue ``` ### `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 updated - `track`: Triggered when tracking events are sent - `feedback`: Triggered when feedback is sent ```vue ``` You can also provide a specific client instance if needed: ```vue ``` ## Content Security Policy (CSP) See [CSP](https://github.com/reflagcom/javascript/blob/main/packages/browser-sdk/README.md#content-security-policy-csp) for info on using Reflag React SDK with CSP ## License MIT License Copyright (c) 2025 Bucket ApS