useSearchParams
Source URL: https://nextjs.org/docs/pages/api-reference/functions/use-search-params
useSearchParams
Section titled “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}</>}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
Section titled “Parameters”const searchParams = useSearchParams()useSearchParams does not take any parameters.
Returns
Section titled “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
Section titled “Behavior”Behavior during pre-rendering
Section titled “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}</>}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
Section titled “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: {} }}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
Section titled “Examples”Updating search params
Section titled “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> </> )}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, value) => { 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
Section titled “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..." />}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
Section titled “Version History”| Version | Changes |
|---|---|
v13.0.0 | useSearchParams introduced. |