diff --git a/webview-ui/src/App.tsx b/webview-ui/src/App.tsx
index 783ddb5138..f9eb5605c2 100644
--- a/webview-ui/src/App.tsx
+++ b/webview-ui/src/App.tsx
@@ -86,12 +86,17 @@ const App = () => {
const [useProviderSignupView, setUseProviderSignupView] = useState(false)
// Check PostHog feature flag for provider signup view
+ // Wait for telemetry to be initialized before checking feature flags
useEffect(() => {
+ if (!didHydrateState || telemetrySetting === "disabled") {
+ return
+ }
+
posthog.onFeatureFlags(function () {
// Feature flag for new provider-focused welcome view
setUseProviderSignupView(posthog?.getFeatureFlag("welcome-provider-signup") === "test")
})
- }, [])
+ }, [didHydrateState, telemetrySetting])
// Create a persistent state manager
const marketplaceStateManager = useMemo(() => new MarketplaceViewStateManager(), [])
diff --git a/webview-ui/src/__tests__/App.spec.tsx b/webview-ui/src/__tests__/App.spec.tsx
index cf6bf9051b..09db361c12 100644
--- a/webview-ui/src/__tests__/App.spec.tsx
+++ b/webview-ui/src/__tests__/App.spec.tsx
@@ -2,9 +2,18 @@
import React from "react"
import { render, screen, act, cleanup } from "@/utils/test-utils"
+import posthog from "posthog-js"
import AppWithProviders from "../App"
+// Mock posthog
+vi.mock("posthog-js", () => ({
+ default: {
+ onFeatureFlags: vi.fn(),
+ getFeatureFlag: vi.fn(),
+ },
+}))
+
vi.mock("@src/utils/vscode", () => ({
vscode: {
postMessage: vi.fn(),
@@ -189,6 +198,7 @@ describe("App", () => {
shouldShowAnnouncement: false,
experiments: {},
language: "en",
+ telemetrySetting: "enabled",
})
})
@@ -338,4 +348,54 @@ describe("App", () => {
expect(chatView.getAttribute("data-hidden")).toBe("false")
expect(screen.queryByTestId("marketplace-view")).not.toBeInTheDocument()
})
+
+ describe("PostHog feature flag initialization", () => {
+ it("waits for state hydration before checking feature flags", () => {
+ mockUseExtensionState.mockReturnValue({
+ didHydrateState: false,
+ showWelcome: false,
+ shouldShowAnnouncement: false,
+ experiments: {},
+ language: "en",
+ telemetrySetting: "enabled",
+ })
+
+ render()
+
+ // PostHog feature flag check should not be called before hydration
+ expect(posthog.onFeatureFlags).not.toHaveBeenCalled()
+ })
+
+ it("checks feature flags after state hydration when telemetry is enabled", () => {
+ mockUseExtensionState.mockReturnValue({
+ didHydrateState: true,
+ showWelcome: false,
+ shouldShowAnnouncement: false,
+ experiments: {},
+ language: "en",
+ telemetrySetting: "enabled",
+ })
+
+ render()
+
+ // PostHog feature flag check should be called after hydration
+ expect(posthog.onFeatureFlags).toHaveBeenCalled()
+ })
+
+ it("does not check feature flags when telemetry is disabled", () => {
+ mockUseExtensionState.mockReturnValue({
+ didHydrateState: true,
+ showWelcome: false,
+ shouldShowAnnouncement: false,
+ experiments: {},
+ language: "en",
+ telemetrySetting: "disabled",
+ })
+
+ render()
+
+ // PostHog feature flag check should not be called when telemetry is disabled
+ expect(posthog.onFeatureFlags).not.toHaveBeenCalled()
+ })
+ })
})