setting-feature-flags-in-storybook

작성자: posthog

Use when writing a Storybook story for a component gated on a feature flag — boolean flags or multivariate/experiment-arm variants. Covers the `featureFlags`…

npx skills add https://github.com/posthog/posthog-foss --skill setting-feature-flags-in-storybook

Setting feature flags in Storybook

[!WARNING] Never call featureFlagLogic.actions.setFeatureFlags(...) from a story. It silently no-ops in the visual-regression runtime (rendering the flag-OFF branch) while passing in jest — so unit tests stay green and the snapshot is wrong. Use the featureFlags story parameter instead.

Mental model: boolean flags always work (they ride the always-merged baseline); variant values need a gate that only the featureFlags parameter opens correctly.

How to use it

This is the stable contract — prefer it over anything in "Under the hood" below.

Boolean flags (flag is simply on)

const meta: Meta = {
  title: 'Scenes/MyScene',
  parameters: {
    featureFlags: [FEATURE_FLAGS.MY_FLAG, FEATURE_FLAGS.OTHER_FLAG],
  },
}

Array entries are flags that evaluate to true. This is the common case.

Multivariate flags (pin a specific variant)

For a flag whose value is a variant string (experiment arms, multivariate rollouts), use the record form — the array form can only express true:

// meta-level: applies to every story in the file
parameters: { featureFlags: { [FEATURE_FLAGS.THEME_OVERRIDE]: 'intent_plus' } }

// per-story: a different arm per story
export const ControlArm: Story = {
    parameters: { featureFlags: { [FEATURE_FLAGS.THEME_OVERRIDE]: 'control' } },
}
export const TreatmentArm: Story = {
    parameters: { featureFlags: { [FEATURE_FLAGS.THEME_OVERRIDE]: 'intent_plus' } },
}

You can mix booleans and variants in one record: { 'some-bool-flag': true, 'my-experiment': 'test_b' }.

[!IMPORTANT] A story's parameters replace the meta's (shallow merge), so a per-story featureFlags drops every flag set at the meta level. Re-list any meta flags you still need — silently losing one renders the flag-off branch and is easy to miss.

Why the obvious approach fails

Setting flags imperatively (featureFlagLogic.actions.setFeatureFlags) works in jest (NODE_ENV==='test') but not in the built visual-regression Storybook. posthog-js loads flags and fires onFeatureFlags with an empty set, which dispatches setFeatureFlags and wipes whatever you set imperatively — so the unit test passes while the snapshot renders the flag-OFF branch. The featureFlags parameter avoids this by writing flags to the always-merged baseline instead (below), so the empty callback can't clobber them.

Do not try to fix this by disabling posthog-js flags (e.g. advanced_disable_feature_flags). The app shell (appLogic.showApp) only renders once receivedFeatureFlags is true, which is set by that same onFeatureFlags callback — suppress it and every Scenes-App/* story stalls behind a 3s timeout and flakes.

Under the hood (implementation detail — may drift)

This explains why the parameter works, for trust and for anyone extending the harness. Treat "How to use it" above as the contract, not this.

withFeatureFlags → setFeatureFlags (frontend/src/mocks/browser.tsx) writes the flags (array or record) straight to window.POSTHOG_APP_CONTEXT.persisted_feature_flags. getPersistedFeatureFlags (frontend/src/lib/logic/featureFlagLogic.ts) reads that as featureFlagLogic's initial value and spyOnFeatureFlags always merges it as the baseline — so both booleans and pinned variants survive the empty onFeatureFlags callback. The only production-side support this needs is getPersistedFeatureFlags accepting the record form (variant values) in addition to the server's array form.

You should not need to touch any of this. If you're extending the harness, that's the seam.

See also

The featureFlags parameter only controls the flag. If a component's render also depends on other runtime state (localStorage, an APP_CONTEXT field, a kea logic that resolves an entry), stage that state too — typically in a small wrapper the story renders that sets it and mounts the logic before rendering the component. Keep that wrapper in the story file; don't add test-only props to the production component to make it renderable.

posthog의 다른 스킬

error-tracking-hono
posthog
PostHog 오류 추적 for Hono
tuning-incremental-sync-config
posthog
동기화의 구성은 ExternalDataSchema에 저장되며, external-data-schemas-partial-update를 통해 언제든지 변경할 수 있습니다. 대부분의 변경은 비파괴적이며(다음 동기화에 적용됨), 일부 변경(sync_type 전환, 기본 키 변경)은 동기화된 데이터 손상을 방지하기 위해 신중한 처리가 필요합니다.
playwright-test
posthog
플레이라이트 테스트를 작성하고, 실행이 잘 되며, 불안정하지 않도록 하세요.
error-tracking-ruby
posthog
PostHog Ruby 오류 추적
authoring-log-alerts
posthog
PostHog 프로젝트의 서비스에 유용하고 노이즈가 적은 로그 알림을 작성합니다. 사용자가 로그에 대한 알림 설정을 요청하거나 추가해야 할 알림을 제안할 때 사용하세요.
making-scenes-tab-aware
posthog
Guides converting PostHog frontend scenes to be tab aware for internal scene tabs. Use when adding or refactoring a `SceneExport` scene, fixing state leaking…
posthog-survey-creator
posthog
PostHog에서 안내 대화를 통해 설문조사를 생성하고 구성합니다. 사용자가 설문조사를 만들거나, 사용자 피드백을 수집하거나, 실행하려 할 때 이 스킬을 사용하세요.
authoring-scouts
posthog
PostHog Signals 스카우트를 작성, 편집 및 조정하는 방법 — 프로젝트를 스캔하고 Signals 인박스에 보고서를 작성하는 예약된 에이전트입니다. 사용자가…