Skip to content
Latchkey

Next.js "useSearchParams() should be wrapped in a suspense boundary" in CI

In the App Router, useSearchParams() opts a component into client-side reading of the URL. During static prerendering Next.js requires a Suspense boundary above it, otherwise the page deopts to client rendering and the build fails the check.

What this error means

next build prints "Error occurred prerendering page" for a route and "useSearchParams() should be wrapped in a suspense boundary at page '/path'", failing the build.

next build
Error occurred prerendering page "/search". Read more:
https://nextjs.org/docs/messages/prerender-error
Error: useSearchParams() should be wrapped in a suspense boundary at page "/search".
Read more: https://nextjs.org/docs/messages/missing-suspense-with-csr-bailout

Common causes

useSearchParams is used without a Suspense boundary

A client component reads search params high in the tree with no <Suspense> ancestor, so static generation cannot bail out cleanly.

The hook sits directly in the page component

Calling the hook in the page itself, rather than a child wrapped in Suspense, forces the whole route to deopt during prerender.

How to fix it

Wrap the consumer in Suspense

  1. Move the component that calls useSearchParams() into its own child.
  2. Render that child inside a <Suspense> boundary with a fallback.
  3. Re-run next build to confirm the route prerenders.
app/search/page.tsx
import { Suspense } from 'react'
import Results from './results'  // calls useSearchParams()

export default function Page() {
  return (
    <Suspense fallback={<p>Loading...</p>}>
      <Results />
    </Suspense>
  )
}

Opt the route out of static generation if appropriate

If the page is inherently dynamic, force dynamic rendering so prerendering does not run.

app/search/page.tsx
export const dynamic = 'force-dynamic'

How to prevent it

  • Isolate hooks that read the URL into Suspense-wrapped children.
  • Reserve force-dynamic for routes that genuinely cannot be static.
  • Run a production build in CI on every PR to catch prerender deopts.

Related guides

Tired of flaky CI? Latchkey auto-heals failed jobs and retries them for you. Start free →