# Suspense Boundaries Client hooks that cause CSR bailout without Suspense boundaries. ## useSearchParams Always requires Suspense boundary in static routes. Without it, the entire page becomes client-side rendered. ```tsx // Bad: Entire page becomes CSR 'use client' import { useSearchParams } from 'next/navigation' export default function SearchBar() { const searchParams = useSearchParams() return
Query: {searchParams.get('q')}
} ``` ```tsx // Good: Wrap in Suspense import { Suspense } from 'react' import SearchBar from './search-bar' export default function Page() { return ( Loading...}> ) } ``` ## usePathname Requires Suspense boundary when route has dynamic parameters. ```tsx // In dynamic route [slug] // Bad: No Suspense 'use client' import { usePathname } from 'next/navigation' export function Breadcrumb() { const pathname = usePathname() return } ``` ```tsx // Good: Wrap in Suspense }> ``` If you use `generateStaticParams`, Suspense is optional. ## Quick Reference | Hook | Suspense Required | |------|-------------------| | `useSearchParams()` | Yes | | `usePathname()` | Yes (dynamic routes) | | `useParams()` | No | | `useRouter()` | No |