diff --git a/apps/web/src/domains/onboarding/pages/pre-chat-flow.tsx b/apps/web/src/domains/onboarding/pages/pre-chat-flow.tsx index c9d907fa490..f18114ef925 100644 --- a/apps/web/src/domains/onboarding/pages/pre-chat-flow.tsx +++ b/apps/web/src/domains/onboarding/pages/pre-chat-flow.tsx @@ -72,7 +72,19 @@ export function PreChatFlow() { (isIOSWeb && !readIOSAppDownloaded()) || (isMacOSWeb && !readMacOsAppDownloaded()); - const [screen, setScreen] = useState(0); + // Native pre-chat restores its position across reloads via sessionStorage + // — without this, an iOS user who's tapped through to the vibe step and + // hot-reloads (or returns after the OS reclaims memory) is silently + // dropped back to the name step. + const [screen, setScreen] = useState(() => { + try { + const saved = sessionStorage.getItem("prechat_native_screen"); + if (saved === "1") return 1; + } catch { + // sessionStorage can throw under privacy modes — ignore. + } + return 0; + }); const [selectedTools, setSelectedTools] = useState>( () => new Set(), ); @@ -190,6 +202,17 @@ export function PreChatFlow() { // ── iOS native flow: NameStep → VibeStep → Privacy → Hatching → Chat ── if (isNative) { if (screen === 0) { + // Both Continue and Skip advance to the vibe step and persist the + // position so the user lands back here on reload — shared closure + // keeps the two callsites from drifting. + const goToVibeStep = () => { + setScreen(1); + try { + sessionStorage.setItem("prechat_native_screen", "1"); + } catch { + // ignore — see initial-state comment. + } + }; return ( setScreen(1)} - onSkip={() => setScreen(1)} + onContinue={goToVibeStep} + onSkip={goToVibeStep} currentStep={0} totalSteps={IOS_TOTAL_STEPS} /> @@ -223,13 +246,25 @@ export function PreChatFlow() { if (trimmedAssistant) { setPendingAssistantName(trimmedAssistant); } + try { + sessionStorage.removeItem("prechat_native_screen"); + } catch { + // ignore — see initial-state comment. + } void navigate(routes.onboarding.privacy); }; return ( setScreen(0)} + onBack={() => { + setScreen(0); + try { + sessionStorage.removeItem("prechat_native_screen"); + } catch { + // ignore — see initial-state comment. + } + }} onContinue={finishNativePreChat} onSkip={finishNativePreChat} currentStep={1} diff --git a/apps/web/src/domains/onboarding/screens/name-step-screen.tsx b/apps/web/src/domains/onboarding/screens/name-step-screen.tsx index 5a22390f727..cea5bdf7862 100644 --- a/apps/web/src/domains/onboarding/screens/name-step-screen.tsx +++ b/apps/web/src/domains/onboarding/screens/name-step-screen.tsx @@ -34,8 +34,15 @@ export function NameStepScreen({
{onBack ? (