Components & Directives
The Nuxt SDK provides Vue components and directives for declarative feature flag usage.
Components
Feature
Conditionally renders content when a feature is on. Set negate to render when it is off — the same pattern as Next.js and .NET <feature negate>.
Single Feature
<template>
<Feature feature-key="new-dashboard">
<NewDashboard />
</Feature>
<Feature feature-key="new-dashboard" negate>
<OldDashboard />
</Feature>
</template>
With Loading State
<template>
<Feature feature-key="premium-feature">
<template #loading>
<SkeletonLoader />
</template>
<template #default>
<PremiumContent />
</template>
</Feature>
<Feature feature-key="premium-feature" negate>
<template #loading>
<SkeletonLoader />
</template>
<template #default>
<UpgradePrompt />
</template>
</Feature>
</template>
Multiple Features (All Required)
<template>
<Feature
:feature-keys="['feature-a', 'feature-b', 'feature-c']"
requirement="all"
>
<FullExperience />
</Feature>
<Feature
:feature-keys="['feature-a', 'feature-b', 'feature-c']"
requirement="all"
negate
>
<p>Enable all features to access this content.</p>
</Feature>
</template>
Multiple Features (Any Required)
<template>
<Feature
:feature-keys="['premium', 'trial', 'beta-access']"
requirement="any"
>
<PremiumFeatures />
</Feature>
</template>
Negated (Show When Disabled)
<template>
<!-- Show when maintenance mode is OFF -->
<Feature feature-key="maintenance-mode" negate>
<MainContent />
</Feature>
<!-- Show when maintenance mode is ON -->
<Feature feature-key="maintenance-mode">
<MaintenanceBanner />
</Feature>
</template>
Directives
v-feature
Conditionally render elements based on feature flags.
Basic Usage
<template>
<div v-feature="'new-feature'">
New feature content
</div>
</template>
Object Syntax
<template>
<div v-feature="{ key: 'feature', requirement: 'all', negate: false }">
Content with options
</div>
</template>
Multiple Features
<template>
<!-- All required (default) -->
<div v-feature="['feature-a', 'feature-b']">
Both features required
</div>
<!-- Any required -->
<div v-feature.any="['feature-a', 'feature-b']">
Either feature enables this
</div>
</template>
Modifiers
<template>
<!-- .any - any feature enables content -->
<div v-feature.any="['a', 'b', 'c']">
Any feature enabled
</div>
<!-- .not - negate the check -->
<div v-feature.not="'beta-feature'">
Show when beta is disabled
</div>
<!-- Combined modifiers -->
<div v-feature.any.not="['feature-a', 'feature-b']">
Show when all features are disabled
</div>
</template>
v-feature-show
Like v-feature but uses visibility: hidden instead of removing from DOM.
Useful when you want to preserve layout space.
<template>
<div v-feature-show="'my-feature'">
Hidden but keeps space when disabled
</div>
<div v-feature-show.any="['a', 'b']">
Visibility-based toggle
</div>
</template>
v-feature-class
Toggle CSS classes based on feature flags.
<template>
<!-- Add 'enabled' class when feature is on -->
<div v-feature-class:enabled="'dark-mode'">
Has 'enabled' class when dark-mode is on
</div>
<!-- Add 'new-ui' class when feature is on -->
<div v-feature-class:new-ui="'redesign'">
Has 'new-ui' class when redesign is on
</div>
<!-- Multiple classes -->
<div
v-feature-class:premium="'premium-tier'"
v-feature-class:beta="'beta-access'"
>
Multiple feature-based classes
</div>
</template>
<style>
.enabled {
background: var(--dark-bg);
}
.new-ui {
border-radius: 12px;
}
</style>
Component Props Reference
Feature Component
| Prop | Type | Default | Description |
|---|---|---|---|
feature-key | string | - | Single feature key to check |
feature-keys | string[] | - | Multiple feature keys to check |
requirement | 'all' | 'any' | 'all' | Logical operator for multiple features |
negate | boolean | false | Invert the check (show when disabled) |
context | object | - | Entity instance for Context Property filters (per widget) |
context-kind | string | - | Kind registered with local registerContext |
Pass entity context on the component — not on setIdentity. See Entity & page context. Clients do not register schemas with the dashboard.
<Feature feature-key="OrderBadge" :context="order" context-kind="Order">
<span class="badge">Featured</span>
</Feature>
Slots
| Slot | Description |
|---|---|
default | Content shown when the gate passes |
loading | Content shown during initial load |
Disabling Components/Directives
If you prefer manual imports:
nuxt.config.ts
export default defineNuxtConfig({
toggly: {
globalComponents: false, // Don't register components globally
globalDirectives: false, // Don't register directives globally
},
})
Then import manually:
<script setup>
import { Feature } from '@ops-ai/nuxt-toggly-client'
import { vFeature } from '@ops-ai/nuxt-toggly-client'
</script>
Best Practices
Use Components for On / Off Paths
<template>
<!-- Good: clear on path + negate off path, with loading -->
<Feature feature-key="checkout-v2">
<template #loading>
<CheckoutSkeleton />
</template>
<template #default>
<CheckoutV2 />
</template>
</Feature>
<Feature feature-key="checkout-v2" negate>
<template #loading>
<CheckoutSkeleton />
</template>
<template #default>
<CheckoutV1 />
</template>
</Feature>
</template>
Use Directives for Simple Toggles
<template>
<!-- Good: Simple show/hide -->
<button v-feature="'dark-mode'" @click="toggleDark">
Toggle Dark Mode
</button>
<span v-feature="'beta-badge'" class="badge">Beta</span>
</template>
Avoid Nesting
<!-- Avoid: Nested feature checks -->
<Feature feature-key="a">
<Feature feature-key="b">
<Content />
</Feature>
</Feature>
<!-- Better: Use feature-keys -->
<Feature :feature-keys="['a', 'b']" requirement="all">
<Content />
</Feature>
Handle Loading States
<template>
<!-- Always consider the loading state for critical UI -->
<Feature feature-key="checkout">
<template #loading>
<!-- Prevent layout shift -->
<div style="min-height: 200px">
<LoadingSpinner />
</div>
</template>
<template #default>
<Checkout />
</template>
</Feature>
</template>