Next.js: useSearchParams を使う Client Component は Suspense で囲む
静的ページ内の Client Component が useSearchParams() を呼ぶとき、Suspense 境界がないと本番ビルドが失敗する。囲んでフォールバックを出す。
使う場面
検索クエリやフィルタを URL の ?q= などで持ち、Client Component で読む実装。開発中は通っても next build だけ落ちる。
やり方
tsx
// app/search/page.tsx(Server Component)
import { Suspense } from 'react'
import { SearchBox } from './search-box'
export default function Page() {
return (
<Suspense fallback={<p>Loading…</p>}>
<SearchBox />
</Suspense>
)
}tsx
// search-box.tsx
'use client'
import { useSearchParams } from 'next/navigation'
export function SearchBox() {
const sp = useSearchParams()
const q = sp.get('q') ?? ''
return <input defaultValue={q} />
}- 公式ドキュメントも、静的レンダリングされるページでは Suspense 境界を要求すると書いている。
- 遷移中の表示は別途 Next.js: useLinkStatus で「押したリンクが遷移待ち」の表示を出す や
loading.js。
注意点
- エージェントやスキャフォールドが
useSearchParamsだけ足して Suspense を付け忘れることがある。ビルドログの指示に従う。 - ページ全体を動的にしたくないときこそ、フックを使う部分だけを Suspense で切り出す。