<1ms Evaluation
Local computation, no network
Edge Caching
Flags cached at CDN edge
Offline Support
Works without internet
Auto Sync
Background updates
Client-Side vs Server-Side Evaluation
Choose the right evaluation strategy based on your needs. Each approach has trade-offs between latency, security, and real-time updates.
Server-Side
- +Secure: rules not exposed to client
- +Real-time: always latest rules
- -Latency: network round-trip
- -Requires: server infrastructure
Client-Side (Local)
- +Fast: sub-millisecond evaluation
- +Offline: works without network
- -Stale: rules may be outdated
- -Exposed: rules visible to client
// Server-side evaluation (API route, server component)
import { platform } from '@/lib/platform'
export async function GET(request: Request) {
const user = await getUser(request)
// Evaluates on server, fetches latest rules
const isEnabled = await platform.flags.isEnabled('new_feature', {
userId: user.id,
context: { plan: user.plan },
})
return Response.json({ enabled: isEnabled })
}When to Use Each
- Server-side: Access control, billing features, sensitive operations
- Client-side: UI variations, cosmetic changes, non-sensitive features
- Hybrid: Most applications - secure where needed, fast everywhere else
Caching Flag Values
Cache flag configurations to reduce latency and network calls. The SDK handles caching automatically with configurable freshness.
import { SylphxProvider } from '@sylphx/sdk/react'
function App() {
return (
<SylphxProvider
projectId="proj_xxx"
// Caching options
cache={{
// Where to store cached flags
storage: 'localStorage', // 'localStorage' | 'sessionStorage' | 'memory'
// How long until cache is considered stale
maxAge: 5 * 60 * 1000, // 5 minutes
// Use stale cache while fetching fresh data
staleWhileRevalidate: true,
// Cache key prefix (for multiple projects)
keyPrefix: 'sylphx_flags_',
}}
>
<MyApp />
</SylphxProvider>
)
}
// Manual cache control
import { flagsClient } from '@sylphx/sdk'
// Force refresh cache
await flagsClient.refresh()
// Clear cache
flagsClient.clearCache()
// Get cache status
const status = flagsClient.getCacheStatus()
// { lastUpdated: Date, isStale: boolean, size: 42 }Cache Levels
Edge Evaluation for Low Latency
Evaluate flags at the edge (CDN) for the best of both worlds: server-side security with client-side speed.
// middleware.ts - runs at the edge
import { NextResponse } from 'next/server'
import { evaluateFlag } from '@sylphx/sdk/edge'
export const config = {
matcher: '/dashboard/:path*',
}
export async function middleware(request: Request) {
const userId = getUserIdFromCookie(request)
// Evaluate at the edge - ~10ms globally
const showNewDashboard = await evaluateFlag('new_dashboard', {
userId,
// Flag rules cached at edge
})
if (showNewDashboard) {
// Rewrite to new dashboard
return NextResponse.rewrite(new URL('/dashboard-v2', request.url))
}
return NextResponse.next()
}Edge Caching Strategy
Offline Mode Support
Keep your app functional even when offline. Cached flag values are used automatically when the network is unavailable.
import { SylphxProvider } from '@sylphx/sdk/react'
function App() {
return (
<SylphxProvider
projectId="proj_xxx"
offline={{
// Enable offline support
enabled: true,
// Pre-load these flags for offline use
preloadFlags: ['core_feature', 'ui_theme', 'api_version'],
// Default values when offline and no cache
defaults: {
core_feature: true,
ui_theme: 'light',
api_version: 'v1',
},
// Callback when going offline/online
onStatusChange: (isOnline) => {
console.log(`Network status: ${isOnline ? 'online' : 'offline'}`)
},
}}
>
<MyApp />
</SylphxProvider>
)
}
// Check network status in components
import { useNetworkStatus } from '@sylphx/sdk/react'
function StatusIndicator() {
const { isOnline, lastSync } = useNetworkStatus()
return (
<div>
{isOnline ? (
<span className="text-green-500">Online</span>
) : (
<span className="text-yellow-500">
Offline (last sync: {lastSync.toLocaleString()})
</span>
)}
</div>
)
}Sync Intervals and Freshness
Configure how often flags are synced and how stale data is handled. Balance freshness against network usage.
// Regular polling for updates
<SylphxProvider
sync={{
// Poll for updates every 60 seconds
pollingInterval: 60 * 1000,
// Only poll when tab is visible
pauseWhenHidden: true,
// Immediate sync on visibility change
syncOnFocus: true,
}}
>Freshness Trade-offs
Fallback Values
Define fallback values for when flags cant be evaluated. Ensures your app always has sensible defaults.
// Global fallback values
<SylphxProvider
projectId="proj_xxx"
fallbacks={{
// Default values for all flags
defaults: {
new_feature: false, // Boolean flag
ui_theme: 'system', // String flag
max_upload_mb: 10, // Number flag
checkout_config: { // JSON flag
maxItems: 25,
enableCoupons: true,
},
},
// Strategy when evaluation fails
strategy: 'default', // 'default' | 'cached' | 'error'
}}
>
// Per-flag fallback
const { enabled } = useFeatureFlag('new_feature', {
fallback: true, // Override default fallback
})
// With loading handling
const { enabled, loading, error } = useFeatureFlag('new_feature')
if (loading) return <Skeleton />
if (error) {
// Log error, use fallback
console.error('Flag evaluation failed:', error)
}
// enabled will be the fallback if evaluation failedFallback Strategies
defaultBest for: Most applicationsUse configured default value. Safest for production.
cachedBest for: High-availability appsUse last known good value from cache. Good for brief outages.
errorBest for: Access control flagsThrow error on failure. Use when flag is critical.
Performance Comparison
Compare evaluation latencies across different strategies.
| Strategy | Latency | Freshness | Use Case |
|---|---|---|---|
| Memory Cache | <0.1ms | Depends on sync | UI flags, hot paths |
| LocalStorage | <1ms | Persisted | Offline support |
| Edge (CDN) | 5-20ms | Seconds | Server components |
| API (Origin) | 50-200ms | Real-time | Critical flags |
API Reference
| Method | Description |
|---|---|
| flagsClient.refresh() | Force sync latest flag rules |
| flagsClient.clearCache() | Clear all cached flag data |
| flagsClient.getCacheStatus() | Get cache age and status |
| useNetworkStatus() | Hook for online/offline status |
| evaluateRules(rules, key, ctx) | Evaluate flag with local rules |