User Feature Flags
Available since:
v2.79.0Introduction
User feature flags allow you to enable or disable specific features on a per-user basis in the webclient. These flags are only fetched and applied when the server-side ERP feature flag FEATURE_USER_FLAGS = "user_feature_flags"
is enabled.
User feature flags provide fine-grained control over UI components and behaviors, allowing for personalized user experiences and gradual feature rollouts.
Prerequisites
Before using user feature flags, ensure that:
- The server has the
FEATURE_USER_FLAGS = "user_feature_flags"
feature enabled - You have access to the
@gisce/react-ooui
package - The user feature flag system is properly configured in your application
Adding a New User Feature Flag
Add the feature key to the enum
Navigate to @gisce/react-ooui
and edit src/models/userFeature.ts
:
export enum UserFeatureKeys { FEATURE_MANY2ONE_DISABLE_ARROW_MENU = "widget.many2one.disable.arrow_menu", FEATURE_MANY2ONE_DISABLE_FOLDER = "widget.many2one.disable.folder", FEATURE_MY_NEW_FEATURE = "my.new.feature.key",}
Using User Feature Flags
Basic Usage
The most common way to use user feature flags is with the useUserFeatureEnabled
hook:
import { useUserFeatureEnabled } from "@/context/ConfigContext";import { UserAllFeatureKeys, UserFeatureKeys } from "@/models/userFeature";
const MyWidget = () => { const disableFolderFeature = useUserFeatureEnabled( UserFeatureKeys.FEATURE_MANY2ONE_DISABLE_FOLDER, );
const disableArrowMenu = useUserFeatureEnabled( UserFeatureKeys.FEATURE_MANY2ONE_DISABLE_ARROW_MENU, );
return ( <div> {!disableFolderFeature && <FolderIcon />} {!disableArrowMenu && <ArrowMenu />} </div> );};
Conditional Rendering
You can use feature flags to conditionally render entire components or parts of your UI:
const ConditionalComponent = () => { const featureEnabled = useUserFeatureEnabled( UserFeatureKeys.FEATURE_MY_NEW_FEATURE, );
if (!featureEnabled) { return null; // Don't render anything }
return <MyNewFeatureComponent />;};
Conditional Styling
Feature flags can also control styling and CSS classes:
const StyledComponent = () => { const compactMode = useUserFeatureEnabled( UserFeatureKeys.FEATURE_COMPACT_MODE, );
return ( <div className={compactMode ? "compact-layout" : "default-layout"}> Content here </div> );};
How It Works
System Architecture
- Server Configuration: The ERP server must have
FEATURE_USER_FLAGS
enabled - Feature Fetching: When a user logs in, the system calls
getUserFeatureFlags
API - State Management: User features are stored in Redux state via
userFeaturesSlice
- Context Propagation: Features are made available through
ConfigContextProvider
- Component Access: Components access features via
useUserFeatureEnabled
hook
Fallback Behavior
When user feature flags are not available (server feature disabled or API error):
- The system falls back to default values defined in
DEFAULT_USER_FEATURES
- No errors are propagated to the main application
- The application continues to function normally with default behaviors
Best Practices
Default Values
- Set sensible defaults that maintain existing behavior
- Consider the impact on new vs. existing users
- Document why specific defaults were chosen
Component Integration
- Check feature flags at the component level, not in business logic
- Use early returns or conditional rendering for better performance
- Keep feature flag logic simple and readable
Troubleshooting
Common Issues
Features not loading
- Verify
FEATURE_USER_FLAGS
is enabled on the server - Check browser network tab for API errors
- Ensure user is properly authenticated
Features not updating
- User features are fetched once per session
- Refresh the page to re-fetch features
- Check Redux DevTools for current feature state
Default values not working
- Verify the feature key exists in
DEFAULT_USER_FEATURES
- Check that the key matches exactly between enum and defaults
- Ensure the feature key is properly exported from
@gisce/react-ooui
Debugging
To debug user feature flags:
- Open Redux DevTools and check the
userFeatures
state - Look for
fetchUserFeaturesError
in browser console - Verify API calls in Network tab
- Check that
ConfigContextProvider
receives the features