@fluxcontrolsdk/js-sdk
v0.2.1
Published
FluxControl JavaScript SDK for feature flags and experimentation
Downloads
484
Maintainers
Readme
FluxControl JavaScript SDK
High-performance JavaScript/TypeScript SDK for feature flags and experimentation in web applications.
Installation
npm install @fluxcontrolsdk/js-sdk
# or
yarn add @fluxcontrolsdk/js-sdk⚙️ Configuration
IMPORTANT: The
apiUrlmust end with/api/v1/sdk
Before using the SDK, ensure you have:
- SDK Key: Your unique SDK key from the FluxControl admin console
- API URL: The complete FluxControl API endpoint
Correct API URL Format
✅ Correct:
apiUrl: 'https://api.fluxcontrol.io/api/v1/sdk'
apiUrl: 'http://localhost:8000/api/v1/sdk'❌ Incorrect:
apiUrl: 'https://api.fluxcontrol.io' // Missing /api/v1/sdk
apiUrl: 'https://api.fluxcontrol.io/api' // Incomplete pathCommon Mistakes
1. Confusing sdkKey with apiKey
❌ Wrong:
<FluxProvider config={{ apiKey: 'your-key' }}> // apiKey is wrong✅ Correct:
<FluxProvider sdkKey="your-key"> // sdkKey is the prop name2. Passing SDK key in config instead of as prop
❌ Wrong:
<FluxProvider config={{ sdkKey: 'your-key', apiUrl: '...' }}>✅ Correct:
<FluxProvider
sdkKey="your-key" // SDK key as prop
config={{ apiUrl: '...' }} // Config for other options
>3. Missing or incomplete API URL
The SDK will warn you if the URL doesn't end with /api/v1/sdk.
Quick Start
Vanilla JavaScript/TypeScript
import { FluxClient } from '@fluxcontrolsdk/js-sdk';
// Initialize client (apiUrl is required)
const client = new FluxClient('your-sdk-key', {
apiUrl: 'https://api.fluxcontrol.io/api/v1/sdk', // Required: FluxControl API endpoint
pollingIntervalMs: 60000 // Optional: polling interval in ms
});
// Create context
const context = {
userId: 'user-123',
attributes: {
plan: 'premium',
country: 'US'
}
};
// Evaluate boolean flag
const enabled = await client.boolVariation('new-feature', context, false);
if (enabled) {
// New feature code
}
// Evaluate string flag
const theme = await client.stringVariation('ui-theme', context, 'light');
// Track custom event
await client.track('button_clicked', context, {
buttonId: 'checkout',
page: 'cart'
});
// Cleanup
client.close();React
import { FluxProvider, useFeature, useTrack } from '@fluxcontrolsdk/js-sdk';
// Wrap your app
function App() {
return (
<FluxProvider
sdkKey="your-sdk-key"
context={{ userId: 'user-123' }}
>
<MyComponent />
</FluxProvider>
);
}
// Use in components
function MyComponent() {
// Evaluate flag
const checkoutFlow = useFeature('checkout-flow', 'standard');
// Track events
const track = useTrack();
const handleClick = () => {
track('button_clicked', { button: 'checkout' });
};
if (checkoutFlow === 'one-click') {
return <OneClickCheckout onClick={handleClick} />;
}
return <StandardCheckout onClick={handleClick} />;
}Note: The
useFeaturehook automatically updates when flags change. No manual polling or state management needed!
API Reference
FluxClient
Main client for evaluating feature flags.
Constructor
new FluxClient(sdkKey: string, config?: Config)Config Options:
apiUrl- Required. FluxControl API endpoint URL (e.g.,'https://api.fluxcontrol.io/api/v1/sdk')pollingIntervalMs- Polling interval in milliseconds (default: 60000)eventFlushIntervalMs- Event flush interval in milliseconds (optional)eventQueueSize- Maximum event queue size (optional)offlineMode- Enable offline mode (default: false)cacheFilePath- Path for local cache file (optional)timeout- Request timeout in milliseconds (optional)
Methods
boolVariation(flagKey, context, defaultValue)
Evaluate a boolean flag.
stringVariation(flagKey, context, defaultValue)
Evaluate a string flag.
numberVariation(flagKey, context, defaultValue)
Evaluate a number flag.
jsonVariation<T>(flagKey, context, defaultValue)
Evaluate a JSON flag with type safety.
track(eventName, context, properties?, value?)
Track a custom event.
close()
Cleanup and stop polling.
React Hooks
FluxProvider
Provider component to wrap your app.
<FluxProvider
sdkKey="your-key"
config={{ edgeUrl: 'https://...' }}
context={{ userId: 'user-123' }}
>
{children}
</FluxProvider>useFeature(flagKey, defaultValue, contextOverride?)
Hook to evaluate a feature flag.
const theme = useFeature('ui-theme', 'light');
const enabled = useFeature('new-feature', false);
const config = useFeature('feature-config', { timeout: 5000 });useFluxClient()
Get the client instance for advanced usage.
const client = useFluxClient();
await client.track('custom_event', context);useTrack()
Hook to track custom events.
const track = useTrack();
track('purchase', { productId: '123' }, 99.99);Context
The context object provides user attributes for targeting:
interface Context {
userId?: string;
sessionId?: string;
attributes?: Record<string, any>;
}Standard attributes:
userId- Unique user identifiersessionId- Session identifierattributes- Custom attributes (plan, country, etc.)
Features
- ✅ TypeScript Support - Full type definitions
- ✅ React Integration - Hooks and Provider
- ✅ Local Caching - localStorage for offline support
- ✅ Auto-refresh - Polling for flag updates
- ✅ Event Tracking - Automatic exposure tracking
- ✅ Edge Evaluation - Secure server-side evaluation
- ✅ SSR Compatible - Works with Next.js and other frameworks
Advanced Usage
Custom Context per Evaluation
const enabled = useFeature('feature', false, {
attributes: { experiment: 'variant-a' }
});Conditional Rendering
function FeatureGate({ flagKey, children }) {
const enabled = useFeature(flagKey, false);
return enabled ? <>{children}</> : null;
}
<FeatureGate flagKey="new-ui">
<NewUI />
</FeatureGate>A/B Testing
function Experiment() {
const variant = useFeature('homepage-hero', 'control');
const track = useTrack();
useEffect(() => {
// Track impression
track('hero_viewed', { variant });
}, [variant]);
const handleClick = () => {
track('hero_clicked', { variant });
};
switch (variant) {
case 'variant-a':
return <HeroA onClick={handleClick} />;
case 'variant-b':
return <HeroB onClick={handleClick} />;
default:
return <HeroControl onClick={handleClick} />;
}
}🔧 Troubleshooting
Common Issues
401 Unauthorized Error
Symptom: Console shows "401 Unauthorized - Check your SDK Key"
Solutions:
- Verify your SDK key is correct in the FluxControl admin console
- Check that you're passing
sdkKeyas a prop, not in config - Ensure the SDK key hasn't expired or been revoked
404 Not Found Error
Symptom: Console shows "404 Not Found - Verify API URL ends with '/api/v1/sdk'"
Solutions:
- Check that
apiUrlends with/api/v1/sdk - Verify the FluxControl API is accessible at that URL
- Check for typos in the URL
Flags Not Updating
Symptom: Flag values don't change when updated in admin console
Solutions:
- Check that
pollingIntervalMsis set (default: 60000ms = 1 minute) - Wait for the next poll cycle
- For React hooks, ensure you're using SDK version 0.2.0+ (automatic reactivity)
- Check browser console for fetch errors
React Hooks Not Reactive
Symptom: useFeature doesn't update when flags change
Solutions:
- Ensure you're using SDK version 0.2.0 or later
- Verify
FluxProvideris wrapping your components - Check that the client is initializing successfully (no console errors)
- The hook automatically subscribes to SDK events - no manual polling needed
Debugging
Check SDK Ready State
const client = new FluxClient('your-key', { apiUrl: '...' });
await client.init();
if (client.isReady) {
console.log('SDK is ready!');
} else {
console.log('SDK not ready - check console for errors');
}Subscribe to SDK Events
client.on('ready', (ruleset) => {
console.log('SDK ready, ruleset loaded:', ruleset);
});
client.on('update', (ruleset) => {
console.log('Ruleset updated:', ruleset);
});
client.on('error', (error) => {
console.error('SDK error:', error);
});Inspect Current Ruleset (Development Only)
// In browser console
const rulesetJson = localStorage.getItem('flux_ruleset_your-sdk-key');
const ruleset = JSON.parse(rulesetJson);
console.log(ruleset);Browser Support
- Chrome/Edge: Latest 2 versions
- Firefox: Latest 2 versions
- Safari: Latest 2 versions
- iOS Safari: iOS 12+
- Android Chrome: Latest 2 versions
License
Internal use only.
