React
This guide provides detailed React code examples demonstrating how to integrate Supaship feature flags using hooks and components. You’ll learn how to set up the provider, access feature flags within your components, and use hooks for dynamic flag evaluation, enabling seamless and type-safe feature flag management in your React applications.
Requirements
- React 16.8+ (hooks support)
- Use JavaScript SDK for react versions < 16.8 (see JavaScript code examples)
Installation
pnpm add @supashiphq/sdk-react
Application Setup
To enable feature flag management throughout your React application, wrap your component tree with the SupaProvider
. The SupaProvider
supplies configuration and context to all child components, making feature flag data and hooks available anywhere in your app. Place it as high as possible in your component hierarchy—typically at the root—so that all components can access feature flag functionality.
import React from 'react'
import { SupaProvider } from '@supashiphq/sdk-react'
import App from './App'
interface AppContext {
userID: string
email: string
version: string
}
function Root() {
const context: AppContext = {
userID: '123',
email: '[email protected]',
version: '1.0.0',
}
// Note: context may not be available at the time of provider initialization,
// and set it to empty object {},
// and update it later using the `setContext` method.
return (
<SupaProvider
config={{
apiKey: 'your-api-key', // Store in environment variable
environment: 'production', // Environment slug
context,
}}>
<App />
</SupaProvider>
)
}
export default Root
Getting Feature Flags
There are two ways to get feature flags in your React application:
- Using the
SupaFeature
component - Using the
useFeature
hook
Using SupaFeature
Component
Using the SupaFeature
component is the simplest way to get a feature flag in your React application. It is a declarative component that takes a feature flag name and a fallback value, and renders the appropriate component based on the feature flag value.
import React from 'react'
import { SupaFeature } from '@supashiphq/sdk-react'
function YourComponent() {
return (
<div>
<SupaFeature
feature='new-navigation'
fallback={false}
variations={{
true: <NewNavigation />,
false: <OldNavigation />,
}}
/>
</div>
)
}
Advanced Usage
Using the SupaFeature
component, you can also use a context override and a loading and error state.
fallback
- The value to return if the feature flag is not found.context
- The context to use for the specific feature flag evaluation.variations
- The variations to use for the feature flag.
// With context override
<SupaFeature
feature='premium-features'
fallback={false}
context={{ plan: 'premium' }} // context override
shouldFetch={user.id} // fetch the feature flag when user.id is available. It is optional.
variations={{
loading: <Loading />, // loading state
error: <Error />, // error state
true: <PremiumFeatures />,
false: <BasicFeatures />,
}}
/>
Using useFeature
Hook
Using the useFeature
hook is the most flexible way to get a feature flag in your React application. It is a hook that takes a feature flag name and a fallback value, and returns the feature flag value. You can also use a context override.
import React from 'react'
import { useFeature } from '@supashiphq/sdk-react'
function MyComponent() {
// Single feature with hook
const { feature: isEnabled } = useFeature('new-navigation', {
fallback: false,
})
return <div>{isEnabled ? <NewNavigation /> : <OldNavigation />}</div>
}
useFeature
with Context Override
Using the useFeature
hook, you can override the default context for a single feature flag evaluation.
const { feature: isEnabled } = useFeature('new-navigation', {
fallback: false,
context: { plan: 'premium' },
})
useFeature
with Loading and Error States
In addition to the feature flag value, the useFeature
hook also returns a loading and error state, which can be useful for displaying a loading spinner or error message while the feature flag is being evaluated.
import React from 'react'
import { useFeature } from '@supashiphq/sdk-react'
function MyComponent() {
// Single feature with hook
const {
feature: isEnabled,
loading,
error,
} = useFeature('new-navigation', {
fallback: false,
})
if (loading) {
return <Loading />
}
if (error) {
return <Error />
}
return isEnabled ? <NewNavigation /> : <OldNavigation />
}
Fetch multiple feature flags with useFeatures
Hook
Using the useFeatures
hook, you can fetch multiple feature flags at once. It is useful when you need to fetch multiple feature flags at once, minimizing the number of API calls and for better performance.
features
- an object with the feature flag names as keys and the fallback values as values.context
- The context to use for the feature flag evaluation. Optional.
import React from 'react'
import { useFeatures } from '@supashiphq/sdk-react'
interface FeatureSet {
'feature-1': boolean
'feature-2': Record<string, any>
}
function Dashboard() {
// Multiple features at once with typing
const { features, loading, error } = useFeatures<FeatureSet>({
features: {
'feature-1': false, // fallback value
'feature-2': { // fallback object
timeout: 5000,
retries: 3,
endpoint: '/api/v1',
},
},
context: { userID: user.id }, // context override
shouldFetch: user.id, // fetch the feature flags when user.id is available.
})
if (loading) {
return <Loading />
}
if (error) {
return <Error />
}
return (
<div>
{features['feature-1'] && <Feature1Component />}
<Feature2Component config={features['feature-2']} />
</div>
)
}
Updating Context
Using the useSupaContext
hook, you can update the default context for all subsequent requests.
This is helpful when the context data is not available at the time of provider initialization, or you need to wait for async data to be available before evaluating feature flags.
updateContext
- The function to update the context.context
- The current context.
import React, { useEffect } from 'react'
import { useSupaContext } from '@supashiphq/sdk-react'
function UserProfile() {
const { updateContext, context } = useSupaContext()
const user = await fetchUser()
useEffect(() => {
updateContext({
...context,
userID: user.id,
email: user.email,
})
}, [updateContext, context, user])
return (
<div>
<h2>Current User ID: {context.userID || 'No user ID'}</h2>
</div>
)
}