From 602f46ac3a99a8d2393199cb5a7581bd6a8ac4e7 Mon Sep 17 00:00:00 2001 From: Manavsaliya Date: Tue, 21 Oct 2025 16:01:57 +0530 Subject: [PATCH 1/2] Fix use-mobile for ssr --- resources/js/hooks/use-mobile.tsx | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/resources/js/hooks/use-mobile.tsx b/resources/js/hooks/use-mobile.tsx index 710ad6e1..34c955cb 100644 --- a/resources/js/hooks/use-mobile.tsx +++ b/resources/js/hooks/use-mobile.tsx @@ -2,20 +2,27 @@ import { useSyncExternalStore } from 'react'; const MOBILE_BREAKPOINT = 768; -const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`); +const mql = (): MediaQueryList | null => { + if (typeof window === 'undefined') return null; + return window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`); +}; function mediaQueryListener(callback: (event: MediaQueryListEvent) => void) { - mql.addEventListener('change', callback); + mql()?.addEventListener('change', callback); return () => { - mql.removeEventListener('change', callback); + mql()?.removeEventListener('change', callback); }; } function isSmallerThanBreakpoint() { - return mql.matches; + return mql()?.matches || false; } export function useIsMobile() { - return useSyncExternalStore(mediaQueryListener, isSmallerThanBreakpoint); + return useSyncExternalStore( + mediaQueryListener, + isSmallerThanBreakpoint, + () => false, + ); } From ad8f35455b3136a5bb1abdc21978792b7431f8f0 Mon Sep 17 00:00:00 2001 From: Manavsaliya Date: Sat, 25 Oct 2025 23:03:26 +0530 Subject: [PATCH 2/2] move server snapshot outside of the hook to use the same reference. --- resources/js/hooks/use-mobile.tsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/resources/js/hooks/use-mobile.tsx b/resources/js/hooks/use-mobile.tsx index 34c955cb..bb0efd42 100644 --- a/resources/js/hooks/use-mobile.tsx +++ b/resources/js/hooks/use-mobile.tsx @@ -15,14 +15,16 @@ function mediaQueryListener(callback: (event: MediaQueryListEvent) => void) { }; } -function isSmallerThanBreakpoint() { +function isSmallerThanBreakpoint(): boolean { return mql()?.matches || false; } +const getServerSnapshot = (): boolean => false; + export function useIsMobile() { return useSyncExternalStore( mediaQueryListener, isSmallerThanBreakpoint, - () => false, + getServerSnapshot, ); }