useSearchParams
useSearchParams is a hook that lets you read the current URL's query string.
useSearchParams returns a read-only version of the URLSearchParams interface.
import { useSearchParams } from 'next/navigation'
export default function Dashboard() {
const searchParams = useSearchParams()
if (!searchParams) {
// Render fallback UI while search params are not yet available
return null
}
const search = searchParams.get('search')
// URL -> `/dashboard?search=my-project`
// `search` -> 'my-project'
return <>Search: {search}</>
}Parameters
const searchParams = useSearchParams()useSearchParams does not take any parameters.
Returns
useSearchParams returns a read-only version of the URLSearchParams interface, or null during prerendering.
The interface includes utility methods for reading the URL's query string:
-
URLSearchParams.get(): Returns the first value associated with the search parameter. For example:URL searchParams.get("a")/dashboard?a=1'1'/dashboard?a=''/dashboard?b=3null/dashboard?a=1&a=2'1'- usegetAll()to get all values -
URLSearchParams.has(): Returns a boolean value indicating if the given parameter exists. For example:URL searchParams.has("a")/dashboard?a=1true/dashboard?b=3false -
Learn more about other read-only methods of
URLSearchParams, including thegetAll(),keys(),values(),entries(),forEach(), andtoString().
Good to know:
useSearchParamsis a React Hook and cannot be used with classes.
Behavior
Behavior during prerendering
For pages that are statically optimized (not using getServerSideProps), useSearchParams will return null during prerendering. After hydration, the value will be updated to the actual search params.
This is because search params cannot be known during static generation as they depend on the request.
import { useSearchParams } from 'next/navigation'
export default function Dashboard() {
const searchParams = useSearchParams()
if (!searchParams) {
// Return a fallback UI while search params are loading
// This prevents hydration mismatches
return <DashboardSkeleton />
}
const search = searchParams.get('search')
return <>Search: {search}</>
}Using with getServerSideProps
When using getServerSideProps, the page is server-rendered on each request and useSearchParams will return the actual search params immediately:
import { useSearchParams } from 'next/navigation'
export default function Dashboard() {
const searchParams = useSearchParams()
// With getServerSideProps, this fallback is never rendered because
// searchParams is always available on the server. However, keeping
// the fallback allows this component to be reused on other pages
// that may not use getServerSideProps.
if (!searchParams) {
return null
}
const search = searchParams.get('search')
return <>Search: {search}</>
}
export async function getServerSideProps() {
return { props: {} }
}Examples
Updating search params
You can use the useRouter hook to update search params:
import { useRouter } from 'next/router'
import { useSearchParams } from 'next/navigation'
import { useCallback } from 'react'
export default function Dashboard() {
const router = useRouter()
const searchParams = useSearchParams()
const createQueryString = useCallback(
(name: string, value: string) => {
const params = new URLSearchParams(searchParams?.toString())
params.set(name, value)
return params.toString()
},
[searchParams]
)
if (!searchParams) {
return null
}
return (
<>
<p>Sort By</p>
<button
onClick={() => {
router.push(router.pathname + '?' + createQueryString('sort', 'asc'))
}}
>
ASC
</button>
<button
onClick={() => {
router.push(router.pathname + '?' + createQueryString('sort', 'desc'))
}}
>
DESC
</button>
</>
)
}Sharing components with App Router
useSearchParams from next/navigation works in both the Pages Router and App Router. This allows you to create shared components that work in either context:
import { useSearchParams } from 'next/navigation'
// This component works in both pages/ and app/
export function SearchBar() {
const searchParams = useSearchParams()
if (!searchParams) {
// Fallback for Pages Router during prerendering
return <input defaultValue="" placeholder="Search..." />
}
const search = searchParams.get('search') ?? ''
return <input defaultValue={search} placeholder="Search..." />
}Good to know: When using this component in the App Router, wrap it in a
<Suspense>boundary for prerendering support.
Version History
| Version | Changes |
|---|---|
v13.0.0 | useSearchParams introduced. |
Was this helpful?