From 40762bc528447f42b39ca5121a9047f376ffbe6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vi=CC=81ctor=20Falco=CC=81n?= Date: Mon, 8 Dec 2025 17:33:54 +0100 Subject: [PATCH] fix: make useIsMobile hook and utility functions SSR-safe - Refactor use-mobile.tsx to use getServerSnapshot for SSR - Add window guard to consoleDebug in debug.ts - Add window guard to isLocalEnvironment in track-event.ts --- resources/js/hooks/use-mobile.tsx | 30 +++++++++++++++++++----------- resources/js/lib/debug.ts | 2 ++ resources/js/lib/track-event.ts | 1 + 3 files changed, 22 insertions(+), 11 deletions(-) diff --git a/resources/js/hooks/use-mobile.tsx b/resources/js/hooks/use-mobile.tsx index 710ad6e1..05890898 100644 --- a/resources/js/hooks/use-mobile.tsx +++ b/resources/js/hooks/use-mobile.tsx @@ -2,20 +2,28 @@ import { useSyncExternalStore } from 'react'; const MOBILE_BREAKPOINT = 768; -const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`); - -function mediaQueryListener(callback: (event: MediaQueryListEvent) => void) { - mql.addEventListener('change', callback); - - return () => { - mql.removeEventListener('change', callback); - }; +function getMediaQueryList(): MediaQueryList | null { + if (typeof window === 'undefined') return null; + return window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`); } -function isSmallerThanBreakpoint() { - return mql.matches; +function subscribe(callback: () => void) { + const mql = getMediaQueryList(); + if (!mql) return () => {}; + + mql.addEventListener('change', callback); + return () => mql.removeEventListener('change', callback); +} + +function getSnapshot() { + const mql = getMediaQueryList(); + return mql ? mql.matches : false; +} + +function getServerSnapshot() { + return false; } export function useIsMobile() { - return useSyncExternalStore(mediaQueryListener, isSmallerThanBreakpoint); + return useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot); } diff --git a/resources/js/lib/debug.ts b/resources/js/lib/debug.ts index d1a6902f..c36698e1 100644 --- a/resources/js/lib/debug.ts +++ b/resources/js/lib/debug.ts @@ -1,4 +1,6 @@ export function consoleDebug(...args: unknown[]): void { + if (typeof window === 'undefined') return; + const isDebugEnabled = localStorage.getItem('debug') === 'true'; const isLocalhost = window.location.hostname === 'localhost'; const isTestDomain = window.location.hostname.includes('.test'); diff --git a/resources/js/lib/track-event.ts b/resources/js/lib/track-event.ts index 83ea89c1..536d89cb 100644 --- a/resources/js/lib/track-event.ts +++ b/resources/js/lib/track-event.ts @@ -12,6 +12,7 @@ export interface TrackEventOptions { } function isLocalEnvironment(): boolean { + if (typeof window === 'undefined') return true; const hostname = window.location.hostname; return hostname === 'localhost' || hostname.endsWith('.test'); }