Client-Side Usage
Segment membership
This package only evaluates published targeting lists. It has no membership write API and must not hold a Backend application key.
Update members from your backend. Use the Nuxt server SDK. Flow.
Use feature flags in your Vue components with auto-imported composables.
Browser metrics are default-on with a public app key. See frontend telemetry configuration and session identity for opt-out, the independent collector URL, explicit events, and cleanup.
Composables
useToggly
The main composable providing access to the full Toggly client.
<script setup>
const {
isReady, // Ref<boolean> - true when initial fetch completes
isLoading, // Ref<boolean> - true during any fetch
features, // Ref<Record<string, boolean>> - all feature states
error, // Ref<Error | null> - last error if any
refresh, // () => Promise<void> - manually refresh features
setIdentity, // (id: string) => Promise<void> - set user identity
destroy, // () => void - cleanup (called automatically)
} = useToggly()
// Wait for features to load
watch(isReady, (ready) => {
if (ready) {
console.log('Features loaded:', features.value)
}
})
// Set user identity after login
async function onLogin(userId: string) {
await setIdentity(userId)
}
</script>
useFeatureFlag
Check if a single feature is enabled.
<script setup>
// Basic usage
const { isEnabled, isLoading } = useFeatureFlag('new-dashboard')
// Reactive feature check
watch(isEnabled, (enabled) => {
if (enabled) {
analytics.track('new_dashboard_shown')
}
})
</script>
<template>
<div v-if="isLoading">Loading...</div>
<NewDashboard v-else-if="isEnabled" />
<OldDashboard v-else />
</template>
useFeatureOff
Check if a feature is disabled (inverted logic).
<script setup>
// Show content when maintenance mode is OFF
const { isEnabled: showContent } = useFeatureOff('maintenance-mode')
</script>
<template>
<MainContent v-if="showContent" />
<MaintenancePage v-else />
</template>
useFeatureGate
Check multiple features with logical operators.
<script setup>
// All features must be enabled
const { isEnabled: hasAll } = useFeatureGate(
['feature-a', 'feature-b', 'feature-c'],
'all'
)
// Any feature enabled
const { isEnabled: hasAny } = useFeatureGate(
['premium', 'trial', 'beta-access'],
'any'
)
// Negated - show when ALL features are OFF
const { isEnabled: showFallback } = useFeatureGate(
['new-ui'],
'all',
true // negate
)
</script>
<template>
<FullExperience v-if="hasAll" />
<PartialExperience v-else-if="hasAny" />
<BasicExperience v-else />
</template>
Variants
Enable enableVariants to fetch assigned variants from
evaluated-variants-signed instead of the boolean evaluated-signed
endpoint. Variant assignment happens worker-side; the client applies local
gates and telemetry on top of the returned assignment.
export default defineNuxtConfig({
toggly: {
appKey: process.env.TOGGLY_APP_KEY,
enableVariants: true,
},
})
useVariant
<script setup>
const { variant, variantValue, isLoading, refresh } = useVariant('pricing-test')
</script>
<template>
<div v-if="isLoading">Loading...</div>
<PricingB v-else-if="variant?.name === 'B'" />
<PricingC v-else-if="variant?.name === 'C'" />
<PricingDefault v-else />
</template>
variant is { name, configurationValue? } | null — null when the
feature is disabled, unassigned, or enableVariants is off. variantValue
is the assigned configurationValue, or null.
useToggly().getVariant
<script setup>
const { getVariant, getVariantValue } = useToggly()
const variant = getVariant('pricing-test') // VariantResult | null
const color = getVariantValue('button-color') // unknown | null
</script>
Both read synchronously from the client's current in-memory state — call
them after isReady is true, or use the reactive useVariant composable
above.
Entity context
Pass a page entity per composable or check — not via setIdentity. See Entity & page context.
The Nuxt client is a browser SDK: local registerContext only. It does not register schemas with the dashboard.
import { registerContext } from '@ops-ai/nuxt-toggly-core'
registerContext('Order', (order) => ({
kind: 'Order',
key: String(order.id),
attributes: { Status: order.status },
}))
<script setup>
const { isFeatureOn } = useToggly()
const order = useOrder()
const showBadge = await isFeatureOn('OrderBadge', order.value, 'Order')
</script>
Gates fail closed without entity context. setIdentity remains user only.
User Identity
Set user identity for percentage-based rollouts and user targeting.
Pass groups and claims at client init (see
Configuration). Runtime
setIdentity changes identity and clears an omitted minted token; it does not
change groups or claims. For complete session changes, use the initialized Core
client's setContext API shown in the linked configuration guide.
Setting Identity
<script setup>
const { setIdentity } = useToggly()
// After user authentication
onMounted(async () => {
const user = await getCurrentUser()
if (user) {
await setIdentity(user.id)
}
})
// On login
async function handleLogin(credentials) {
const user = await login(credentials)
await setIdentity(user.id)
}
// On logout - clear identity
async function handleLogout() {
await setIdentity('')
}
</script>
Persistent Identity
Identity is persisted to localStorage by default (configurable):
export default defineNuxtConfig({
toggly: {
persistIdentity: true, // default
},
})
Refreshing Features
Features auto-refresh based on the refreshInterval config. You can also refresh manually:
<script setup>
const { refresh, isLoading } = useToggly()
async function forceRefresh() {
await refresh()
}
</script>
<template>
<button @click="forceRefresh" :disabled="isLoading">
Refresh Features
</button>
</template>
Error Handling
<script setup>
const { error, isReady } = useToggly()
watch(error, (err) => {
if (err) {
console.error('Toggly error:', err)
// Features keep last-known-good values when available, then fall back to defaults
}
})
</script>
<template>
<div v-if="error" class="error-banner">
Feature service unavailable. Using cached values.
</div>
</template>
For callback-based reporting with the direct client and the shared fallback contract, see Reliability and Error Handling.
SSR Considerations
The SDK handles SSR automatically:
- Server: Features fetched and cached server-side
- Hydration: Client receives server state, no flash
- Client: Takes over with reactive updates
<script setup>
const { isReady, isEnabled } = useFeatureFlag('my-feature')
// isReady is true immediately on client if SSR provided data
// No loading flash on hydration
</script>
Disable SSR for Specific Features
For client-only features, use ClientOnly:
<template>
<ClientOnly>
<Feature feature-key="client-only-feature">
<ClientOnlyComponent />
</Feature>
</ClientOnly>
</template>
Offline Support
Enable localStorage persistence for offline access:
export default defineNuxtConfig({
toggly: {
persistFeatures: true, // Cache features locally
},
})
When the API is unavailable, the SDK will:
- Use cached features from localStorage
- Fall back to
featureDefaultsif no cache - Retry on next refresh interval
TypeScript
All composables are fully typed:
import type { UseFeatureFlagReturn, UseTogglyReturn, UseVariantReturn, VariantResult } from '@ops-ai/nuxt-toggly'
const flag: UseFeatureFlagReturn = useFeatureFlag('my-feature')
const toggly: UseTogglyReturn = useToggly()
const variant: UseVariantReturn = useVariant('pricing-test')
const result: VariantResult | null = toggly.getVariant('pricing-test')