---
name: nextjs-use-search-params-suspense
description: Pattern for using useSearchParams hook with Suspense boundary in Next.js. Covers the required combination of 'use client' directive and Suspense wrapper when accessing URL query parameters in client components. Use when building search interfaces, filters, pagination, or any feature that needs to read/manipulate URL query parameters client-side.
allowed-tools: Read, Write, Edit, Glob, Grep, Bash
---
# Next.js: useSearchParams with Suspense Pattern
## Pattern Overview
**The useSearchParams hook requires TWO things:**
1. Component must have `'use client'` directive
2. Component must be wrapped in a `` boundary
This is a Next.js requirement, not optional!
## Why This Pattern?
**useSearchParams** reads URL query parameters:
- `/search?q=shoes` → `searchParams.get('q')` returns `"shoes"`
- `/products?category=electronics&sort=price` → Read multiple params
**Why Suspense?**
Next.js uses React 18's Suspense to handle the async nature of reading URL params during server-side rendering and hydration.
## The Pattern
### Single-File Pattern (Recommended)
```typescript
// app/page.tsx
import { Suspense } from 'react';
import SearchComponent from './SearchComponent';
export default function Page() {
return (
Loading...}>
);
}
// app/SearchComponent.tsx
'use client';
import { useSearchParams } from 'next/navigation';
export default function SearchComponent() {
const searchParams = useSearchParams();
const query = searchParams.get('q') || '';
return (
Search Results for: {query}
);
}
```
### Inline Pattern (Single File)
Sometimes you want everything in one file:
```typescript
// app/page.tsx
'use client';
import { Suspense } from 'react';
import { useSearchParams } from 'next/navigation';
function SearchContent() {
const searchParams = useSearchParams();
const query = searchParams.get('q') || '';
return (
;
}
```
### ❌ Mistake 2: Missing Suspense Wrapper
```typescript
// ❌ WRONG - Missing Suspense
'use client';
import { useSearchParams } from 'next/navigation';
export default function Page() {
const searchParams = useSearchParams(); // Will cause issues!
return
{searchParams.get('q')}
;
}
```
```typescript
// ✅ CORRECT
'use client';
import { Suspense } from 'react';
import { useSearchParams } from 'next/navigation';
function SearchContent() {
const searchParams = useSearchParams();
return
{searchParams.get('q')}
;
}
export default function Page() {
return (
Loading...}>
);
}
```
### ❌ Mistake 3: Using in Server Component
```typescript
// ❌ WRONG - Trying to use in server component
import { useSearchParams } from 'next/navigation';
export default async function Page() { // async = server component
const searchParams = useSearchParams(); // ERROR! Hooks don't work in server components
return
...
;
}
```
```typescript
// ✅ CORRECT - Use searchParams prop in server components
export default async function Page({
searchParams,
}: {
searchParams: Promise<{ q?: string }>;
}) {
const { q } = await searchParams;
return
Query: {q}
;
}
```
## Server vs Client searchParams
| Feature | Server Component | Client Component |
|---------|-----------------|------------------|
| Access method | `searchParams` prop | `useSearchParams()` hook |
| Requires 'use client' | ❌ No | ✅ Yes |
| Requires Suspense | ❌ No | ✅ Yes |
| Can be async | ✅ Yes | ❌ No |
| Can update params | ❌ No (use Link/redirect) | ✅ Yes (use router.push) |
| Best for | Initial load, SEO | Dynamic filters, real-time updates |
## Quick Checklist
When using useSearchParams:
- [ ] Add `'use client'` directive at top of file
- [ ] Import `Suspense` from 'react'
- [ ] Import `useSearchParams` from 'next/navigation'
- [ ] Wrap component using `useSearchParams` in ``
- [ ] Provide a fallback to Suspense
- [ ] Call `useSearchParams()` inside wrapped component
- [ ] Use `.get()`, `.has()`, or `.getAll()` to read params
## Summary
**useSearchParams with Suspense:**
- ✅ Requires `'use client'` directive
- ✅ Requires `` wrapper
- ✅ Use for client-side URL param reading
- ✅ Combine with `useRouter()` for updating params
- ✅ Best for filters, search, pagination
- ❌ NOT for server components (use `searchParams` prop instead)
This is the recommended pattern for client-side URL parameter handling in Next.js App Router.