TidyLinker.com
TypeScript
Pull Request Opened
PR #142 opened: fix: avoid module-load window access in SSR bundle
Summary
Fixes TIDY-LINKER-32 — Inertia\Ssr\SsrException: window is not defined on /admin.
Two modules touched window at the top level, so importing them under Node SSR threw before any component could render:
resources/js/hooks/use-mobile.tsxcreated theMediaQueryListeagerly withwindow.matchMedia(...). It's transitively imported by the admin sidebar, so the SSR build ofAdmin/Dashboardblew up the moment Node evaluated the chunk (the production stack trace pointed atapp-logo-Bh8rFSgu.js:147— the chunk that bundled this hook).resources/js/echo.tsassignedwindow.Pusherandwindow.Echoat module scope. Pulled in viaapp-header/app-sidebar-header→use-notifications→use-echo→echo. Same SSR latent bug, would crash any authenticated page once the first one was fixed.
Fix
use-mobile.tsx— movedwindow.matchMediacalls inside thesubscribe/getSnapshotcallbacks, and suppliedgetServerSnapshottouseSyncExternalStoreso SSR returnsfalse(not mobile) without touchingwindow.echo.ts— wrapped thewindow.Pusher/new Echo()side effects inif (typeof window !== 'undefined'). Consumer hooks only callecho.private(...)insideuseEffect, which never runs server-side, so the API surface is unchanged.
Test plan
-
npm run build:ssrsucceeds. - Loading the SSR
app-logo-*chunk in Node no longer throwswindow is not defined. - POSTing a render request to the freshly-built SSR server for
Admin/Dashboardevaluates the component (only failure was a missing prop in the smoke fixture, which proves SSR ran past the original failure point). -
npm run lintandnpm run typespass (only an unrelated pre-existing tsconfig deprecation warning). - Verify
/adminrenders without an SSR exception in production after deploy.
Generated by Claude Code
+26
additions
-20
deletions
2
files changed