From b1709b714e5e5d591351db51f7d2b31fb201fe74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Falc=C3=B3n?= Date: Tue, 5 May 2026 08:45:44 +0100 Subject: [PATCH] fix(onboarding): guard window access in SSR (#351) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Problem Production SSR crashes repeatedly when rendering the Onboarding page: ``` ReferenceError: window is not defined at Onboarding (/app/bootstrap/ssr/assets/index-BEtdcHXd.js:2295) ``` The `useMemo` reading `?step=` from the URL accessed `window.location.search` directly, which fails during Inertia SSR. Observed ~7+ times in production logs between 18:35–21:37 UTC. ## Fix Add `typeof window === 'undefined'` guard before reading the URL. Returns `undefined` on the server so the step initializer falls back to default behavior; client hydration re-runs and reads the URL. ## Related logs - `Inertia\Ssr\SsrException` — Onboarding page - Other SSR-touching files (`welcome.tsx`, `auth/login.tsx`) verified safe (window inside `useEffect` or already guarded). --- resources/js/pages/onboarding/index.tsx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/resources/js/pages/onboarding/index.tsx b/resources/js/pages/onboarding/index.tsx index 114519c9..6676b645 100644 --- a/resources/js/pages/onboarding/index.tsx +++ b/resources/js/pages/onboarding/index.tsx @@ -71,6 +71,9 @@ export default function Onboarding({ // Read ?step= from URL to allow deep-linking into a specific step const initialStep = useMemo((): OnboardingStep | undefined => { + if (typeof window === 'undefined') { + return undefined; + } const params = new URLSearchParams(window.location.search); const step = params.get('step') as OnboardingStep | null; return step && VALID_STEPS.includes(step) ? step : undefined;