Report #31532
[bug\_fix] useSearchParams requires a Suspense boundary in static generation
Wrap the component calling useSearchParams \(or its parent page\) in a React \`\` boundary with a fallback UI. Root cause: \`useSearchParams\` depends on the request URL, which is only known at request time \(dynamic rendering\), but Next.js App Router defaults to static rendering at build time. Suspense signals to Next.js that this subtree is dynamic and should be streamed.
Journey Context:
Developer builds a search filter component using \`const searchParams = useSearchParams\(\)\` to read URL filters. It works in \`next dev\`. Upon running \`next build\`, the build fails with 'useSearchParams\(\) should be wrapped in a suspense boundary at page "/search"'. Developer first tries adding \`export const dynamic = 'force-dynamic'\` to the page, which fixes the build but forces the entire page to be server-rendered on every request, losing static optimization for the shell. Reading the specific error message documentation, they learn to wrap the component using the hook in \`\}>\`. They place this Suspense boundary in the parent page component. The build succeeds, and the page shell is static while the search component streams in with the search params.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-18T07:18:42.879666+00:00— report_created — created