useSearchParams
useSearchParams
is a Client Component hook that lets you read the current URL's query string.
useSearchParams
returns a read-only version of the URLSearchParams
interface.
'use client'
import { useSearchParams } from 'next/navigation'
export default function SearchBar() {
const searchParams = useSearchParams()
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, which 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=3
null
/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=1
true
/dashboard?b=3
false
-
Learn more about other read-only methods of
URLSearchParams
, including thegetAll()
,keys()
,values()
,entries()
,forEach()
, andtoString()
.
Good to know:
useSearchParams
is a Client Component hook and is not supported in Server Components to prevent stale values during partial rendering.- If an application includes the
/pages
directory,useSearchParams
will returnReadonlyURLSearchParams | null
. Thenull
value is for compatibility during migration since search params cannot be known during pre-rendering of a page that doesn't usegetServerSideProps
Behavior
Static Rendering
If a route is statically rendered, calling useSearchParams()
will cause the tree up to the closest Suspense
boundary to be client-side rendered.
This allows a part of the page to be statically rendered while the dynamic part that uses searchParams
is client-side rendered.
You can reduce the portion of the route that is client-side rendered by wrapping the component that uses useSearchParams
in a Suspense
boundary. For example:
'use client'
import { useSearchParams } from 'next/navigation'
export default function SearchBar() {
const searchParams = useSearchParams()
const search = searchParams.get('search')
// This will not be logged on the server when using static rendering
console.log(search)
return <>Search: {search}</>
}
import { Suspense } from 'react'
import SearchBar from './search-bar'
// This component passed as a fallback to the Suspense boundary
// will be rendered in place of the search bar in the initial HTML.
// When the value is available during React hydration the fallback
// will be replaced with the `<SearchBar>` component.
function SearchBarFallback() {
return <>placeholder</>
}
export default function Page() {
return (
<>
<nav>
<Suspense fallback={<SearchBarFallback />}>
<SearchBar />
</Suspense>
</nav>
<h1>Dashboard</h1>
</>
)
}
Dynamic Rendering
If a route is dynamically rendered, useSearchParams
will be available on the server during the initial server render of the Client Component.
Good to know: Setting the
dynamic
route segment config option toforce-dynamic
can be used to force dynamic rendering.
For example:
'use client'
import { useSearchParams } from 'next/navigation'
export default function SearchBar() {
const searchParams = useSearchParams()
const search = searchParams.get('search')
// This will be logged on the server during the initial render
// and on the client on subsequent navigations.
console.log(search)
return <>Search: {search}</>
}
import SearchBar from './search-bar'
export const dynamic = 'force-dynamic'
export default function Page() {
return (
<>
<nav>
<SearchBar />
</nav>
<h1>Dashboard</h1>
</>
)
}
Server Components
Pages
To access search params in Pages (Server Components), use the searchParams
prop.
Layouts
Unlike Pages, Layouts (Server Components) do not receive the searchParams
prop. This is because a shared layout is not re-rendered during navigation which could lead to stale searchParams
between navigations. View detailed explanation.
Instead, use the Page searchParams
prop or the useSearchParams
hook in a Client Component, which is re-rendered on the client with the latest searchParams
.
Examples
Updating searchParams
You can use useRouter
or Link
to set new searchParams
. After a navigation is performed, the current page.js
will receive an updated searchParams
prop.
export default function ExampleClientComponent() {
const router = useRouter()
const pathname = usePathname()
const searchParams = useSearchParams()!
// Get a new searchParams string by merging the current
// searchParams with a provided key/value pair
const createQueryString = useCallback(
(name: string, value: string) => {
const params = new URLSearchParams(searchParams)
params.set(name, value)
return params.toString()
},
[searchParams]
)
return (
<>
<p>Sort By</p>
{/* using useRouter */}
<button
onClick={() => {
// <pathname>?sort=asc
router.push(pathname + '?' + createQueryString('sort', 'asc'))
}}
>
ASC
</button>
{/* using <Link> */}
<Link
href={
// <pathname>?sort=desc
pathname + '?' + createQueryString('sort', 'desc')
}
>
DESC
</Link>
</>
)
}
Version History
Version | Changes |
---|---|
v13.0.0 | useSearchParams introduced. |
Was this helpful?