Next.js で「useSearchParams() should be wrapped in a suspense boundary」が解消できない
App Router で `useSearchParams()` を Suspense 境界なしに使うと、ビルド(静的生成)時にこのエラーで失敗する。
呼び出す部分を `<Suspense>` で包めば解決する。
#nextjs#app-router#useSearchParams#suspense#build
公開: 更新:
要約
App Router の useSearchParams() は、URL のクエリに依存するためクライアントでしか確定しません。
Suspense で囲まずに使うと、ページ全体がクライアント描画(CSR)に倒れてしまうため、Next.js はビルド時にこのエラーで止めます。
解決は「使う場所だけを <Suspense> で囲む」ことです。
よくある原因
useSearchParams()を呼ぶ Client Component が<Suspense>の外にある。- ページ全体が CSR にフォールバックするのを Next.js が防いでいる。
output: 'export'(静的生成)構成のため、ビルド時に必ず検出される。
解決策
1. Suspense で包む
クエリを読む部分を小さなコンポーネントに分け、<Suspense> で囲みます。
静的シェルが保たれます。
import { Suspense } from 'react';
import { SearchBox } from './search-box';
export default function Page() {
return (
<Suspense fallback={<p>読み込み中…</p>}>
<SearchBox />
</Suspense>
);
}'use client';
import { useSearchParams } from 'next/navigation';
export function SearchBox() {
const q = useSearchParams().get('q');
return <input defaultValue={q ?? ''} />;
}2. 動的描画に切り替える
静的生成が不要なら、Server Component で export const dynamic = 'force-dynamic' を置くか、connection() を呼んでオンデマンド描画にします。
この場合 Suspense は不要です。