Skip to main content

feature-flags

Use when: implementing, creating, testing, or debugging feature flags in Primer React. Covers useFeatureFlag hook, FeatureFlags provider, DefaultFeatureFlags, FeatureFlagScope, Storybook integration, and the feature flag lifecycle at GitHub.

معلومات المصدر

المستودع
primer/react
آخر نشاط في المصدر
٢٩ أكتوبر ٢٠٢٦ في ١٤:٠٧
لغة SKILL.md المكتشفة
الإنجليزية
النجوم
٣٬٩٣٣
التفرعات
٧٢٦

خيارات التثبيت

يُحدَّد Prompt الذي يراجع المصدر أولًا بشكل افتراضي. يمكنك التبديل إلى أمر مباشر أو تنزيل نسخة محلية.

مراجعة ملفات المصدر

اقرأ SKILL.md وأي ملفات مرافقة يعرضها SkillsMP قبل أن تقرر التثبيت.

عرض SKILL.md

SKILL.md
تعليمات المصدر · معاينة للقراءة فقط
name
feature-flags
description
Use when: implementing, creating, testing, or debugging feature flags in Primer React. Covers useFeatureFlag hook, FeatureFlags provider, DefaultFeatureFlags, FeatureFlagScope, Storybook integration, and the feature flag lifecycle at GitHub.
# Feature Flags in Primer React Feature flags provide a way to incrementally build and deliver changes in Primer alongside the feature flag system at GitHub. They help build confidence in changes and improve the reliability of releases. ## Architecture Feature flags are implemented in `packages/react/src/FeatureFlags/` with these core pieces: | File | Purpose | | ------------------------ | ----------------------------------------------- | | `FeatureFlags.tsx` | React context provider component | | `useFeatureFlag.ts` | Hook to check if a flag is enabled | | `FeatureFlagScope.ts` | Class that manages flag collections and merging | | `DefaultFeatureFlags.ts` | Default flag values (all flags listed here) | | `FeatureFlagContext.ts` | React context definition | | `index.ts` | Public exports | ### Exports Feature flags are exported from `@primer/react/experimental`: ```tsx import {FeatureFlags, useFeatureFlag, DefaultFeatureFlags} from '@primer/react/experimental' ``` They are NOT exported from the main `@primer/react` entry point. ## How to Use a Feature Flag in a Component ### 1. Add the flag to DefaultFeatureFlags Register your flag in `packages/react/src/FeatureFlags/DefaultFeatureFlags.ts` with a default value of `false`: ```typescript export const DefaultFeatureFlags = FeatureFlagScope.create({ // ...existing flags... primer_react_my_new_feature: false, }) ``` ### 2. Use `useFeatureFlag` in your component ```tsx import {useFeatureFlag} from '../FeatureFlags' function MyComponent() { const enabled = useFeatureFlag('primer_react_my_new_feature') if (enabled) { return <NewBehavior /> } return <CurrentBehavior /> } ``` ### 3. Naming conventions - Prefix with `primer_react_` for flags in the `@primer/react` package - Use snake_case: `primer_react_my_feature_name` ## Patterns ### Change behavior conditionally ```tsx function ExampleComponent({children}) { const enabled = useFeatureFlag('primer_react_my_feature') return ( <button onClick={() => { if (enabled) { // new behavior } else { // current behavior } }} > {children} </button> ) } ``` ### Toggle between two component versions ```tsx function ExampleComponent(props) { const enabled = useFeatureFlag('primer_react_my_feature') if (enabled) { return <ExampleComponentNext {...props} /> } return <ExampleComponentClassic {...props} /> } ``` ### Data attributes on DOM elements ```tsx function MyOverlay() { const enabled = useFeatureFlag('primer_react_my_feature') return <div data-my-feature={enabled ? '' : undefined} /> } ``` ## Real Codebase Examples ### CSS anchor positioning (`packages/react/src/AnchoredOverlay/AnchoredOverlay.tsx`) ```tsx const cssAnchorPositioning = useFeatureFlag('primer_react_css_anchor_positioning') useEffect(() => { if (cssAnchorPositioning && !hasLoadedAnchorPositioningPolyfill.current) { applyAnchorPositioningPolyfill() hasLoadedAnchorPositioningPolyfill.current = true } }, [open, overlayRef, updateOverlayRef, cssAnchorPositioning]) ``` ### Breadcrumbs overflow (`packages/react/src/Breadcrumbs/Breadcrumbs.tsx`) ```tsx const overflowMenuEnabled = useFeatureFlag('primer_react_breadcrumbs_overflow_menu') ``` ## Testing with Feature Flags Wrap your component with the `FeatureFlags` provider to set flag values in tests: ```tsx import {FeatureFlags} from '../../FeatureFlags' // Test with flag enabled render( <FeatureFlags flags={{primer_react_my_feature: true}}> <MyComponent /> </FeatureFlags>, ) // Test with flag disabled (or omit the wrapper to use default values from DefaultFeatureFlags) render( <FeatureFlags flags={{primer_react_my_feature: false}}> <MyComponent /> </FeatureFlags>, ) ``` ### Key testing behaviors - Unknown flags default to `false` - Nested `FeatureFlags` providers merge flags — inner values override outer values - You should test both enabled and disabled states ## Storybook Integration ### Enable flag in a specific story ```tsx import {FeatureFlags} from '../../FeatureFlags' export const WithFeatureEnabled = () => ( <FeatureFlags flags={{primer_react_my_feature: true}}> <MyComponent /> </FeatureFlags> ) export const WithFeatureDisabled = () => <MyComponent /> ``` ### Enable flag in all stories Storybook's global preview (`packages/react/.storybook/preview.jsx`) already wraps all stories in a `FeatureFlags` provider, using `DefaultFeatureFlags` as the source of default values and toolbar options. In most cases you only need to register your flag in `DefaultFeatureFlags.ts`; you do not need to manually add it to the `FeatureFlags` wrapper. To enable a flag globally via environment, add its exact flag name (for example, `primer_react_my_feature`) to the `featureFlagEnvList` set in `preview.jsx`, and set the corresponding env var to `1` (for example, `VITE_primer_react_my_feature=1`). The preview code reads `import.meta.env[\`VITE*${flag}\`]`, so the part after `VITE*` must match the flag string exactly. ## Feature Flag Lifecycle 1. **Create** — Register the flag in `DefaultFeatureFlags.ts` with value `false` 2. **Implement** — Use `useFeatureFlag()` in components, write tests for both states 3. **Test in Storybook** — Create stories with the flag enabled/disabled 4. **Ship** — Merge to main; the flag remains off by default 5. **Enable at GitHub** — Use DevPortal to enable for specific actors, then staffship, then GA 6. **Remove** — Once fully rolled out, remove the flag from code and `DefaultFeatureFlags.ts` ### Temporarily testing in Dotcom CI Set your flag to `true` in `DefaultFeatureFlags.ts` to enable it by default for CI testing. Set it back to `false` before merging. ## FeatureFlags Provider Internals - `FeatureFlagScope.create(flags)` — Creates a scope from a plain object `{[key: string]: boolean}` - `FeatureFlagScope.merge(a, b)` — Merges two scopes; `b` values override `a` - The `FeatureFlags` component merges parent context flags with the provided `flags` prop - `DefaultFeatureFlags` is the initial context value — it defines all known flags ## Current Feature Flags Check `packages/react/src/FeatureFlags/DefaultFeatureFlags.ts` for the current list of all registered feature flags and their default values.
عرض على GitHub