Usage Guide
Client-Side Usage
Basic Flag Checking
Use the useFeatureFlags composable in your Vue components:
vue
<script setup>
const { isEnabled, getVariant, getValue } = useFeatureFlags()
// Check if a flag is enabled
const showNewFeature = isEnabled('newFeature')
// Get variant assignment
const variant = getVariant('experiment')
// Get flag value
const maxItems = getValue('maxItems')
</script>
<template>
<div>
<!-- Simple conditional rendering -->
<NewFeature v-if="showNewFeature" />
<!-- Variant-based rendering -->
<div v-if="variant === 'treatment'">
Treatment version
</div>
</div>
</template>Using the v-feature Directive
The v-feature directive provides a declarative way to conditionally render elements:
vue
<template>
<!-- Show element if flag is enabled -->
<div v-feature="'newDashboard'">
<h1>Welcome to the New Dashboard!</h1>
</div>
<!-- Show for specific variant -->
<button v-feature="'buttonDesign:control'">
Original Button
</button>
<button v-feature="'buttonDesign:treatment'">
New Button Design
</button>
</template>Note: The v-feature directive is client-side only. For server-rendered content, use v-if with isEnabled().
Accessing All Flags
vue
<script setup>
const { flags } = useFeatureFlags()
// Access all resolved flags
console.log(flags.value)
// {
// newDashboard: { enabled: true, value: true },
// experiment: { enabled: true, value: 'treatment', variant: 'treatment' }
// }
// Watch for flag changes
watch(flags, (newFlags) => {
console.log('Flags updated:', newFlags)
})
</script>Manually Refreshing Flags
vue
<script setup>
const { fetch, flags } = useFeatureFlags()
// Refresh flags after user login
async function handleLogin(user) {
await loginUser(user)
// Refresh flags to get user-specific flags
await fetch()
console.log('Updated flags:', flags.value)
}
</script>Server-Side Usage
API Routes
Use getFeatureFlags in your server routes:
ts
// server/api/dashboard.ts
export default defineEventHandler(async (event) => {
const { isEnabled, getVariant, getValue } = getFeatureFlags(event)
// Feature gating
if (!isEnabled('newDashboard')) {
throw createError({
statusCode: 404,
message: 'Dashboard not available'
})
}
// Get variant for A/B test
const layoutVariant = getVariant('dashboardLayout')
// Get configuration value
const maxWidgets = getValue('maxDashboardWidgets') || 6
return {
layout: layoutVariant,
maxWidgets,
data: await fetchDashboardData()
}
})Middleware
Use flags in server middleware for request-level logic:
ts
// server/middleware/feature-gate.ts
export default defineEventHandler((event) => {
const { isEnabled } = getFeatureFlags(event)
// Block access to beta routes
if (event.path.startsWith('/api/beta') && !isEnabled('betaAccess')) {
throw createError({
statusCode: 403,
message: 'Beta access required'
})
}
})Accessing All Flags
ts
export default defineEventHandler((event) => {
const { flags } = getFeatureFlags(event)
// Return all flags to client
return {
features: Object.entries(flags).reduce((acc, [key, flag]) => {
acc[key] = {
enabled: flag.enabled,
variant: flag.variant
}
return acc
}, {} as Record<string, any>)
}
})Working with Variants
A/B Testing
vue
<script setup>
const { getVariant, getValue } = useFeatureFlags()
// Get which variant the user is assigned to
const buttonVariant = getVariant('buttonDesign')
// Get the value for the user's variant
const buttonConfig = getValue('buttonDesign')
// Track which variant is shown
onMounted(() => {
analytics.track('button_variant_shown', { variant: buttonVariant })
})
function handleClick() {
analytics.track('button_clicked', { variant: buttonVariant })
}
</script>
<template>
<button
:class="`btn-${buttonConfig.color}`"
@click="handleClick"
>
{{ buttonConfig.text }}
</button>
</template>Gradual Rollouts
ts
// feature-flags.config.ts
export default defineFeatureFlags(() => ({
newCheckout: {
enabled: true,
variants: [
{ name: 'old', weight: 80, value: false },
{ name: 'new', weight: 20, value: true } // 20% get new checkout
]
}
}))vue
<script setup>
const { getValue } = useFeatureFlags()
const useNewCheckout = getValue('newCheckout')
</script>
<template>
<NewCheckoutFlow v-if="useNewCheckout" />
<OldCheckoutFlow v-else />
</template>Type Safety
The module automatically generates TypeScript types:
ts
const { isEnabled, getValue } = useFeatureFlags()
// ✅ Type-safe - flag exists
isEnabled('newDashboard')
// ❌ TypeScript error - flag not declared
isEnabled('unknownFlag')
// ✅ Type-safe value access
const maxItems: number = getValue('maxItems')Best Practices
1. Conditional Rendering
vue
<template>
<div>
<!-- Simple flag check -->
<NewFeature v-if="isEnabled('newFeature')" />
<!-- Combined with other conditions -->
<BetaFeature
v-if="isEnabled('betaFeature') && user.canAccess"
:user="user"
/>
<!-- Toggle between versions -->
<NewDashboard v-if="isEnabled('newDashboard')" />
<LegacyDashboard v-else />
</div>
</template>2. Server-Side Protection
Always protect sensitive features on both client and server:
ts
// server/api/premium-feature.ts
export default defineEventHandler(async (event) => {
const { isEnabled } = getFeatureFlags(event)
if (!isEnabled('premiumFeature')) {
throw createError({
statusCode: 403,
message: 'Premium feature not available'
})
}
return {
// Premium feature data
}
})3. Use Computed Properties
vue
<script setup>
const { isEnabled, getValue } = useFeatureFlags()
// Cache flag checks in computed properties
const features = computed(() => ({
newDashboard: isEnabled('newDashboard'),
darkMode: isEnabled('darkMode'),
maxItems: getValue('maxItems') || 20
}))
</script>
<template>
<div v-if="features.newDashboard">
<Dashboard
:dark="features.darkMode"
:max-items="features.maxItems"
/>
</div>
</template>4. Track Variant Exposure
vue
<script setup>
const { getVariant } = useFeatureFlags()
const variant = getVariant('experiment')
// Track when user sees a variant
onMounted(() => {
if (variant) {
analytics.track('experiment_viewed', { variant })
}
})
</script>Next Steps
- Learn about Context-Aware Configuration for dynamic flags
- Explore Variants & A/B Testing for experiments
- Check the API Reference for all available methods
- Review Best Practices for effective flag management