できない.dev

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> で囲む」ことです。

よくある原因

  1. useSearchParams() を呼ぶ Client Component が <Suspense> の外にある。
  2. ページ全体が CSR にフォールバックするのを Next.js が防いでいる。
  3. 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 は不要です。

この記事は役立ちましたか?