Files
flyer-crawler.projectium.com/src/hooks/useFeatureFlag.ts
Torben Sorensen 61f24305fb
All checks were successful
Deploy to Test Environment / deploy-to-test (push) Successful in 22m13s
ADR-024 Feature Flagging Strategy
2026-01-28 23:23:45 -08:00

87 lines
2.6 KiB
TypeScript

// src/hooks/useFeatureFlag.ts
import { useMemo } from 'react';
import config from '../config';
/**
* Union type of all available feature flag names.
* This type is derived from the config.featureFlags object to ensure
* type safety and autocomplete support when checking feature flags.
*
* @example
* const flagName: FeatureFlagName = 'newDashboard'; // Valid
* const invalid: FeatureFlagName = 'nonexistent'; // TypeScript error
*/
export type FeatureFlagName = keyof typeof config.featureFlags;
/**
* React hook to check if a feature flag is enabled.
*
* Feature flags are loaded from environment variables at build time and
* cannot change during runtime. This hook memoizes the result to prevent
* unnecessary re-renders when the component re-renders.
*
* @param flagName - The name of the feature flag to check (must be a valid FeatureFlagName)
* @returns boolean indicating if the feature is enabled (true) or disabled (false)
*
* @example
* // Basic usage - conditionally render UI
* function Dashboard() {
* const isNewDashboard = useFeatureFlag('newDashboard');
*
* if (isNewDashboard) {
* return <NewDashboard />;
* }
* return <LegacyDashboard />;
* }
*
* @example
* // Track feature flag usage with analytics
* function FeatureComponent() {
* const isExperimentalAi = useFeatureFlag('experimentalAi');
*
* useEffect(() => {
* if (isExperimentalAi) {
* analytics.track('experimental_ai_enabled');
* }
* }, [isExperimentalAi]);
*
* return isExperimentalAi ? <AiFeature /> : null;
* }
*
* @see docs/adr/0024-feature-flagging-strategy.md
*/
export function useFeatureFlag(flagName: FeatureFlagName): boolean {
return useMemo(() => config.featureFlags[flagName], [flagName]);
}
/**
* React hook to get all feature flags and their current states.
*
* This hook is useful for debugging, admin panels, or components that
* need to display the current feature flag configuration. The returned
* object is a shallow copy to prevent accidental mutation of the config.
*
* @returns Record mapping each feature flag name to its boolean state
*
* @example
* // Display feature flag status in an admin panel
* function FeatureFlagDebugPanel() {
* const flags = useAllFeatureFlags();
*
* return (
* <ul>
* {Object.entries(flags).map(([name, enabled]) => (
* <li key={name}>
* {name}: {enabled ? 'Enabled' : 'Disabled'}
* </li>
* ))}
* </ul>
* );
* }
*
* @see docs/adr/0024-feature-flagging-strategy.md
*/
export function useAllFeatureFlags(): Record<FeatureFlagName, boolean> {
return useMemo(() => ({ ...config.featureFlags }), []);
}