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 pre-rendering.
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 pre-rendering
For pages that are statically optimized (not using getServerSideProps), useSearchParams will return null during pre-rendering. 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 pre-rendering
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 static rendering support.
Version History
| Version | Changes |
|---|---|
v13.0.0 | useSearchParams introduced. |
Was this helpful?