Skip to content

Commit 85030ed

Browse files
fix(react): PostHogFeature should render fallback when flag doesn't exist (#3146)
1 parent 24eb966 commit 85030ed

File tree

3 files changed

+61
-15
lines changed

3 files changed

+61
-15
lines changed

.changeset/small-areas-melt.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@posthog/react': patch
3+
---
4+
5+
Fix PostHogFeature component to properly handle undefined flags and false values

packages/react/src/components/PostHogFeature.tsx

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -31,21 +31,23 @@ export function PostHogFeature({
3131
const shouldTrackInteraction = trackInteraction ?? true
3232
const shouldTrackView = trackView ?? true
3333

34-
if (isUndefined(match) || variant === match) {
35-
const childNode: React.ReactNode = isFunction(children) ? children(payload) : children
36-
return (
37-
<VisibilityAndClickTrackers
38-
flag={flag}
39-
options={visibilityObserverOptions}
40-
trackInteraction={shouldTrackInteraction}
41-
trackView={shouldTrackView}
42-
onInteract={() => captureFeatureInteraction({ flag, posthog, flagVariant: variant })}
43-
onView={() => captureFeatureView({ flag, posthog, flagVariant: variant })}
44-
{...props}
45-
>
46-
{childNode}
47-
</VisibilityAndClickTrackers>
48-
)
34+
if (!isUndefined(variant)) {
35+
if (isUndefined(match) || variant === match) {
36+
const childNode: React.ReactNode = isFunction(children) ? children(payload) : children
37+
return (
38+
<VisibilityAndClickTrackers
39+
flag={flag}
40+
options={visibilityObserverOptions}
41+
trackInteraction={shouldTrackInteraction}
42+
trackView={shouldTrackView}
43+
onInteract={() => captureFeatureInteraction({ flag, posthog, flagVariant: variant })}
44+
onView={() => captureFeatureView({ flag, posthog, flagVariant: variant })}
45+
{...props}
46+
>
47+
{childNode}
48+
</VisibilityAndClickTrackers>
49+
)
50+
}
4951
}
5052
return <>{fallback}</>
5153
}

packages/react/src/components/__tests__/PostHogFeature.test.tsx

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,4 +249,43 @@ describe('PostHogFeature component', () => {
249249
fireEvent.click(screen.getByTestId('hi_example_feature_1_payload'))
250250
expect(posthog.capture).toHaveBeenCalledTimes(1)
251251
})
252+
253+
it('should not render when flag does not exist and no match is specified', () => {
254+
render(
255+
<PostHogProvider client={posthog}>
256+
<PostHogFeature flag={'nonexistent_flag'}>
257+
<div data-testid="helloDiv">Hello</div>
258+
</PostHogFeature>
259+
</PostHogProvider>
260+
)
261+
262+
expect(screen.queryByTestId('helloDiv')).not.toBeInTheDocument()
263+
expect(posthog.capture).not.toHaveBeenCalled()
264+
})
265+
266+
it('should render fallback when flag does not exist (like new-cta example)', () => {
267+
render(
268+
<PostHogProvider client={posthog}>
269+
<PostHogFeature flag={'new-cta'} fallback={<div data-testid="oldButton">Old Button</div>}>
270+
<div data-testid="newButton">New Button</div>
271+
</PostHogFeature>
272+
</PostHogProvider>
273+
)
274+
275+
expect(screen.queryByTestId('newButton')).not.toBeInTheDocument()
276+
expect(screen.queryByTestId('oldButton')).toBeInTheDocument()
277+
expect(posthog.capture).not.toHaveBeenCalled()
278+
})
279+
280+
it('should render content when match=false and flag variant is false', () => {
281+
render(
282+
<PostHogProvider client={posthog}>
283+
<PostHogFeature flag={'test_false'} match={false}>
284+
<div data-testid="disabledUI">Show when disabled</div>
285+
</PostHogFeature>
286+
</PostHogProvider>
287+
)
288+
289+
expect(screen.queryByTestId('disabledUI')).toBeInTheDocument()
290+
})
252291
})

0 commit comments

Comments
 (0)