@flagpole/vue v0.0.1
Flagpole Vue SDK
Vue.js SDK for the Flagpole feature flag management system. Provides real-time feature flag updates, A/B testing capabilities, and seamless integration with Vue 3 applications.
Installation
npm install @flagpole/client-vue socket.io-client
# or
yarn add @flagpole/client-vue socket.io-clientQuick Start
1. Setup with Plugin (Recommended)
// main.ts
import { createApp } from "vue";
import { createFlagpole } from "@flagpole/client-vue";
import App from "./App.vue";
const app = createApp(App);
app.use(
createFlagpole({
apiKey: "your-api-key-here",
environments: ["development"], // Optional
})
);
app.mount("#app");2. Use in Components
<template>
<div>
<!-- Using directive -->
<div v-feature-flag="'newFeature'">
<h2>New Feature Content</h2>
</div>
<!-- Using composable -->
<div v-if="isPremiumEnabled">
<PremiumContent />
</div>
<!-- Loading and error states -->
<div v-if="isLoading">Loading flags...</div>
<div v-if="error">Error: {{ error.message }}</div>
</div>
</template>
<script setup lang="ts">
import { useFeatureFlag, useFeatureFlags } from "@flagpole/client-vue";
// Individual flag
const isPremiumEnabled = useFeatureFlag("premiumFeature");
// All flags with state
const { flags, isLoading, error } = useFeatureFlags();
</script>Features
✅ Vue 3 Composition API - Built for modern Vue development
✅ Real-time Updates - WebSocket integration for instant flag changes
✅ TypeScript Support - Full type safety and IntelliSense
✅ Multiple Usage Patterns - Composables, directives, and global methods
✅ Vue Router Integration - Route guards based on feature flags
✅ Environment Filtering - Show flags only for specific environments
✅ Error Handling - Comprehensive error states and fallbacks
✅ SSR Compatible - Works with Nuxt.js and other SSR frameworks
API Reference
Setup Methods
Plugin Installation
import { createFlagpole } from '@flagpole/client-vue';
app.use(createFlagpole({
apiKey: string;
environments?: string[]; // ['development', 'staging', 'production']
}));Provider Component
<FeatureFlagProvider api-key="your-key" :environments="['dev']">
<YourApp />
</FeatureFlagProvider>Composables
useFeatureFlags()
const {
flags, // ComputedRef<Record<string, FeatureFlag>>
isLoading, // ComputedRef<boolean>
error, // ComputedRef<Error | null>
isFeatureEnabled, // (flagName: string) => boolean
} = useFeatureFlags();useFeatureFlag(flagName)
const isEnabled = useFeatureFlag("flagName"); // ComputedRef<boolean>Directive
<!-- Show when flag is enabled -->
<div v-feature-flag="'flagName'">Content</div>
<!-- Show when flag is disabled -->
<div v-feature-flag:not="'maintenanceMode'">Content</div>Global Methods (Plugin Only)
// Template
$isFeatureEnabled("flagName");
// Script
this.$isFeatureEnabled("flagName");Usage Examples
Conditional Rendering
<template>
<div>
<!-- Method 1: Directive -->
<div v-feature-flag="'newDashboard'">
<NewDashboard />
</div>
<!-- Method 2: Composable -->
<div v-if="isBetaEnabled">
<BetaFeature />
</div>
<!-- Method 3: Complex conditions -->
<div v-if="showAdvancedFeatures">
<AdvancedPanel />
</div>
</div>
</template>
<script setup lang="ts">
import { computed } from "vue";
import { useFeatureFlag } from "@flagpole/client-vue";
const isBetaEnabled = useFeatureFlag("betaFeatures");
const isPremiumUser = useFeatureFlag("premiumAccess");
const showAdvancedFeatures = computed(
() => isBetaEnabled.value && isPremiumUser.value
);
</script>Route Protection
// router/index.ts
import { createRouter } from "vue-router";
function featureFlagGuard(flagName: string, redirectTo: string = "/") {
return (to, from, next) => {
const app = to.matched[0]?.instances?.default?.$parent?.$root;
const isEnabled = app?.$isFeatureEnabled?.(flagName);
isEnabled ? next() : next(redirectTo);
};
}
const routes = [
{
path: "/beta",
component: BetaFeature,
beforeEnter: featureFlagGuard("betaAccess", "/coming-soon"),
},
];A/B Testing
<template>
<component :is="checkoutVariant" />
</template>
<script setup lang="ts">
import { computed } from "vue";
import { useFeatureFlags } from "@flagpole/client-vue";
const { flags } = useFeatureFlags();
const checkoutVariant = computed(() => {
const experiment = flags.value["checkoutExperiment"];
const variant = experiment?.conditions?.variant || "control";
return {
control: CheckoutV1,
variantA: CheckoutV2,
variantB: CheckoutV3,
}[variant];
});
</script>Custom Composable
// composables/useNavigation.ts
import { computed } from "vue";
import { useFeatureFlag } from "@flagpole/client-vue";
export function useNavigation() {
const hasNewNav = useFeatureFlag("newNavigation");
const hasAdmin = useFeatureFlag("adminPanel");
const menuItems = computed(() => {
const items = [{ label: "Home", path: "/" }];
if (hasNewNav.value) {
items.push({ label: "Dashboard", path: "/dashboard" });
}
if (hasAdmin.value) {
items.push({ label: "Admin", path: "/admin" });
}
return items;
});
return { menuItems };
}Configuration
Environment Variables
// .env
VITE_FLAGPOLE_API_KEY = fp_live_your_api_key_here;
VITE_ENVIRONMENT = development;
// main.ts
app.use(
createFlagpole({
apiKey: import.meta.env.VITE_FLAGPOLE_API_KEY,
environments: [import.meta.env.VITE_ENVIRONMENT],
})
);TypeScript Configuration
// types/flags.ts
export interface AppFeatureFlags {
newDashboard: boolean;
premiumFeatures: boolean;
betaAccess: boolean;
}
// Custom typed composable
export function useTypedFeatureFlag<K extends keyof AppFeatureFlags>(
flagKey: K
): ComputedRef<boolean> {
return useFeatureFlag(flagKey);
}Testing
// tests/FeatureComponent.test.ts
import { mount } from "@vue/test-utils";
import { createFlagpole } from "@flagpole/client-vue";
const mockFlagpole = createFlagpole({
apiKey: "test-key",
});
describe("FeatureComponent", () => {
it("shows feature when flag is enabled", () => {
const wrapper = mount(FeatureComponent, {
global: {
plugins: [mockFlagpole],
},
});
// Test enabled state
});
});SSR Support (Nuxt.js)
// plugins/flagpole.client.ts
import { createFlagpole } from "@flagpole/client-vue";
export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.vueApp.use(
createFlagpole({
apiKey: useRuntimeConfig().public.flagpoleApiKey,
environments: [useRuntimeConfig().public.environment],
})
);
});Requirements
- Vue.js 3.3+
- Node.js 16+
- Modern browser with WebSocket support
Migration Guide
From Vue 2
This SDK is built for Vue 3. For Vue 2 support, please use the legacy version or consider upgrading to Vue 3.
From Other Flag Libraries
Replace your existing feature flag calls with Flagpole composables:
// Before (other library)
const isEnabled = useFlag("feature-name");
// After (Flagpole)
const isEnabled = useFeatureFlag("feature-name");Contributing
- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature - Commit changes:
git commit -m 'Add amazing feature' - Push to branch:
git push origin feature/amazing-feature - Open a Pull Request
Support
License
MIT © Flagpole
Made with ❤️ for the Vue.js community
8 months ago