From 2b4e2c7061e88f490ad9789f70b5cdf9247f92ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=B0=95=EC=84=B1=EC=A3=BC?= Date: Thu, 12 Nov 2026 00:37:11 +0900 Subject: [PATCH] =?UTF-8?q?fix(web):=20=EB=8D=B0=EC=8A=A4=ED=81=AC?= =?UTF-8?q?=ED=86=B1=20=EC=B0=BD=20=EB=AA=A8=EB=B0=94=EC=9D=BC=20=ED=8F=AD?= =?UTF-8?q?=EC=97=90=EC=84=9C=20=EC=BD=9C=EB=B0=B4=20=ED=99=94=EB=A9=B4=20?= =?UTF-8?q?=EC=A0=91=EA=B7=BC=20=EA=B0=80=EB=8A=A5=ED=95=98=EA=B2=8C=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/web/src/routes/callvan.index.tsx | 14 +++++++------- apps/web/src/utils/hooks/layout/useMediaQuery.ts | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/apps/web/src/routes/callvan.index.tsx b/apps/web/src/routes/callvan.index.tsx index 88ddc209..76fb4b50 100644 --- a/apps/web/src/routes/callvan.index.tsx +++ b/apps/web/src/routes/callvan.index.tsx @@ -9,7 +9,7 @@ import CallvanList from 'components/Callvan/components/CallvanList'; import CallvanPageLayout from 'components/Callvan/components/CallvanPageLayout'; import { type CallvanParams, parseCallvanQuery } from 'components/Callvan/utils/callvanQuery'; import ROUTES from 'static/routes'; -import useMediaQuery from 'utils/hooks/layout/useMediaQuery'; +import useMediaQuery, { MOBILE_QUERY } from 'utils/hooks/layout/useMediaQuery'; import useIsLoggedIn from 'utils/hooks/state/useIsLoggedIn'; import useMount from 'utils/hooks/state/useMount'; import useInfiniteScroll from 'utils/hooks/ui/useInfiniteScroll'; @@ -57,14 +57,13 @@ function useCallvanParams(initialParams: CallvanParams): CallvanParams { function CallvanPage({ initialParams }: Awaited>) { const routeNavigate = useNavigate(); const isMobile = useMediaQuery(); - const mounted = useMount(); - // 서버가 이미 걸러내지만, 창 크기를 줄여 모바일 폭이 된 뒤 넓히는 경우를 위해 남긴다. + // 콜밴은 모바일 폭에서만 연다. 기기(UA)가 아니라 화면 폭으로 판단해 창을 좁힌 데스크톱도 허용한다. useEffect(() => { - if (mounted && !isMobile) { + if (!isMobile && !window.matchMedia(MOBILE_QUERY).matches) { routeNavigate({ href: ROUTES.Main(), replace: true }); } - }, [mounted, isMobile, routeNavigate]); + }, [isMobile, routeNavigate]); const params = useCallvanParams(initialParams); @@ -114,8 +113,9 @@ function CallvanContent({ params }: CallvanContentProps) { } const loadPage = definePageLoad(async ({ search: query, queryClient }, _cacheControl, serverRequest) => { - if (serverRequest.device !== 'mobile') { - throw redirect({ href: ROUTES.Main(), statusCode: 302 }); + // 화면 이동은 브라우저에서 실행되므로 실제 폭으로 바로 거른다. SSR은 폭을 모르니 화면 컴포넌트가 거른다. + if (typeof window !== 'undefined' && !window.matchMedia(MOBILE_QUERY).matches) { + throw redirect({ href: ROUTES.Main() }); } const params = parseCallvanQuery(query, DEFAULT_PARAMS); diff --git a/apps/web/src/utils/hooks/layout/useMediaQuery.ts b/apps/web/src/utils/hooks/layout/useMediaQuery.ts index 76c9166b..97f6f507 100644 --- a/apps/web/src/utils/hooks/layout/useMediaQuery.ts +++ b/apps/web/src/utils/hooks/layout/useMediaQuery.ts @@ -2,7 +2,7 @@ import { useSyncExternalStore } from 'react'; import { useServerRequest } from 'utils/ssr/useServerRequest'; -const MOBILE_QUERY = '(max-width: 576px)'; +export const MOBILE_QUERY = '(max-width: 576px)'; function subscribeToMediaQuery(query: string) { return (onStoreChange: () => void) => {