公式ドキュメントに書いてある通りなのですが、ほんのりハマったのでメモ。
ことの発端
src/app/page.tsx
import { ServerComponent } from '@/components/ServerComponent'; export default function Home() { return ( <ServerComponent /> ); }
src/components/SeverComponent
import { ClientComponent } from '@/components/ClientComponent'; export function ServerComponent() { return ( <ClientComponent /> ); }
src/components/ClientComponent
'use client'; import { useSearchParams } from 'next/navigation'; export function ClientComponent() { const searchParams = useSearchParams(); return ( <div> <p>timestamp: { searchParams.get('timestamp') }</p> </div> ); }
こんな感じのサイトを作っていた際、
yarn dev
では問題が起こらないのですが、
yarn build
実行時に、
useSearchParams() should be wrapped in a suspense boundary at page "/". Read more: https://nextjs.org/docs/messages/missing-suspense-with-csr-bailout
と、エラーが発生しました。
提示されたURL に目を通してみると、
Suspenseを使わずにuseSearchParamsを使うと、ページ全体がクライアント側レンダリングに設定されるということが判明。
確かにURLが決まるまでレンダリングされる内容が決まらないことは理解できるのですが、'use client'でクライアントコンポーネントにしていてもページ全体に影響を及ぼすようです。
解決策
Suspenseを設定すればOKです。
今回の場合は、
src/components/SeverComponent
import { Suspense } from 'react'; import { ClientComponent } from '@/components/ClientComponent'; export function ServerComponent() { return ( <Suspense> <ClientComponent /> </Suspense> ); }
とすれば良い気がします。