← 전체 글로 돌아가기

Next.js

Next.js 정적 빌드에서 useSearchParams 경고를 Suspense로 분리한 기록

검색 페이지를 정적으로 빌드할 때 나타난 useSearchParams 경고를 컴포넌트 경계와 fallback으로 나눠 해결한 과정이다.

개발 서버에서는 멀쩡했는데 빌드에서 멈췄다

URL에서 검색어를 읽는 컴포넌트를 추가한 뒤 next dev에서는 잘 열렸다. 배포 파이프라인의 next build에서는 클라이언트 렌더링 경계가 필요하다는 오류가 났다. useSearchParams() 하나가 페이지 전체의 정적 렌더링 조건을 바꾼 셈이었다.

브라우저 영역만 Suspense 안으로 옮겼다

페이지에서 훅을 직접 호출하지 않고 검색 UI를 Client Component로 분리했다. Suspense의 fallback은 느린 환경에서도 검색 영역이 사라진 것처럼 보이지 않도록 안내 문구로 정했다.

// app/search/page.tsx
import {Suspense} from 'react'
import SearchControls from './SearchControls'

export default function SearchPage() {
  return <main>
    <h1>검색</h1>
    <Suspense fallback={<p>검색 조건을 불러오는 중입니다.</p>}>
      <SearchControls />
    </Suspense>
  </main>
}

// app/search/SearchControls.tsx
'use client'
import {useSearchParams} from 'next/navigation'
export default function SearchControls() {
  const params = useSearchParams()
  const keyword = params.get('q') ?? ''
  return <p>현재 검색어: {keyword || '없음'}</p>
}

배포 전 확인 목록

  • next dev가 아니라 next build를 실행했는가
  • 훅 컴포넌트에 use client가 있는가
  • 쿼리스트링이 없는 URL도 정상인가
  • 새로고침과 뒤로가기로 검색 조건이 바뀌는가
  • fallback이 로딩 중 사용자의 위치를 설명하는가

핵심은 경고를 숨기는 것이 아니라 URL을 읽어야 하는 브라우저 영역을 정적 페이지와 분리한 데 있었다.