From ccf98063b6c1f400d69787241d183327193179ad Mon Sep 17 00:00:00 2001 From: Michael Matloka Date: Fri, 8 May 2026 08:57:48 +0000 Subject: [PATCH] feat(onboarding): auto-enable PostHog internal signal sources Make Error Tracking, Support, and Session Replay opt-out during onboarding so a brand-new project's inbox starts populated without an extra click. Existing configs (enabled or disabled) are left alone, so users who have explicitly toggled a source keep their choice. Generated-By: PostHog Code Task-Id: 98a038aa-87c5-41a3-b6ab-dac91119107f --- .../inbox/hooks/useSignalSourceManager.ts | 26 +++++++++++++++++++ .../onboarding/components/SignalsStep.tsx | 12 +++++++++ 2 files changed, 38 insertions(+) diff --git a/apps/code/src/renderer/features/inbox/hooks/useSignalSourceManager.ts b/apps/code/src/renderer/features/inbox/hooks/useSignalSourceManager.ts index 70d1c86dc..5bfbf591e 100644 --- a/apps/code/src/renderer/features/inbox/hooks/useSignalSourceManager.ts +++ b/apps/code/src/renderer/features/inbox/hooks/useSignalSourceManager.ts @@ -62,6 +62,15 @@ const ALL_SOURCE_PRODUCTS: (keyof SignalSourceValues)[] = [ "conversations", ]; +// Sources powered by PostHog itself (no external integration required). These +// are auto-enabled the first time a project reaches the onboarding signals step +// so the inbox is opt-out, not opt-in. +const POSTHOG_INTERNAL_SOURCES: (keyof SignalSourceValues)[] = [ + "error_tracking", + "conversations", + "session_replay", +]; + function computeValues( configs: SignalSourceConfig[] | undefined, ): SignalSourceValues { @@ -378,6 +387,22 @@ export function useSignalSourceManager() { ], ); + // Create configs (enabled) for any PostHog-internal source that has none. + // Sources with an existing config (enabled or disabled) are left alone so we + // never override an explicit user choice. + const autoEnableInternalSources = useCallback(async () => { + if (!client || !projectId || !configs) return; + + const missing = POSTHOG_INTERNAL_SOURCES.filter( + (product) => !configs.some((c) => c.source_product === product), + ); + if (missing.length === 0) return; + + for (const product of missing) { + void handleToggle(product, true); + } + }, [client, projectId, configs, handleToggle]); + const handleSetupComplete = useCallback(async () => { const completedSource = setupSource; setSetupSource(null); @@ -476,6 +501,7 @@ export function useSignalSourceManager() { handleSetup, handleSetupComplete, handleSetupCancel, + autoEnableInternalSources, evaluations: displayEvaluations, evaluationsUrl, handleToggleEvaluation, diff --git a/apps/code/src/renderer/features/onboarding/components/SignalsStep.tsx b/apps/code/src/renderer/features/onboarding/components/SignalsStep.tsx index 5ae2f3ea1..744f7437d 100644 --- a/apps/code/src/renderer/features/onboarding/components/SignalsStep.tsx +++ b/apps/code/src/renderer/features/onboarding/components/SignalsStep.tsx @@ -7,6 +7,7 @@ import { Button, Flex, Text } from "@radix-ui/themes"; import detectiveHog from "@renderer/assets/images/hedgehogs/detective-hog.png"; import { useQueryClient } from "@tanstack/react-query"; import { motion } from "framer-motion"; +import { useEffect, useRef } from "react"; import { OnboardingHogTip } from "./OnboardingHogTip"; import { StepActions } from "./StepActions"; @@ -27,10 +28,21 @@ export function SignalsStep({ onNext, onBack }: SignalsStepProps) { handleSetupComplete, handleSetupCancel, evaluationsUrl, + autoEnableInternalSources, } = useSignalSourceManager(); const { data: me } = useMeQuery(); const isStaff = me?.is_staff ?? false; + // Auto-enable PostHog-internal sources on first load so the inbox is opt-out + // during onboarding. The manager skips any source that already has a config. + const autoEnabledRef = useRef(false); + useEffect(() => { + if (autoEnabledRef.current) return; + if (isLoading) return; + autoEnabledRef.current = true; + void autoEnableInternalSources(); + }, [isLoading, autoEnableInternalSources]); + const anyEnabled = displayValues.session_replay || displayValues.error_tracking ||