Skip to main content
Glama

Bucket Feature Flags MCP Server

Official
by reflagcom
README.md19.9 kB
# 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 <script setup lang="ts"> import { ReflagProvider } from "@reflag/vue-sdk"; </script> <ReflagProvider :publishable-key="publishableKey" :context="{ user: { id: 'user_123', name: 'John Doe', email: 'john@acme.com' }, 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 ```vue <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()](#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 <ReflagProvider :publishable-key="publishableKey" :context="{ user: { id: 'user_123', name: 'John Doe', email: 'john@acme.com' }, 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: ```vue <ReflagProvider :publishable-key="publishableKey" :user="{ id: 'user_123', name: 'John Doe', email: 'john@acme.com' }" :company="{ id: 'acme_inc', plan: 'pro' }" :other-context="{ source: 'web' }" > <!-- your app --> </ReflagProvider> ``` > [!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. ## `<ReflagProvider>` component The `<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: - `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. 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 to `true` to enable debug logging to the console, - `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 <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 The `<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 ```vue <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: "john@acme.com" }, 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: ```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 flags object containing context and flag data - 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. ## `<ReflagClientProvider>` component The `<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 ```vue <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-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 <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()` 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 <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()` 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 <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](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 <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()` 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 <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()` Returns the `ReflagClient` used by the `ReflagProvider`. The client offers more functionality that is not directly accessible through the other composables. ```vue <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()` 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. ```vue <script setup> import { useIsLoading } from "@reflag/vue-sdk"; import { Spinner } from "./Spinner"; const isLoading = useIsLoading(); </script> <template> <!-- your component content --> </template> ``` ### `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 <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: ```vue <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](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

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/reflagcom/bucket-javascript-sdk'

If you have feedback or need assistance with the MCP directory API, please join our Discord server