Skip to content
API ReferenceFunctionsuseSearchParams

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.

pages/dashboard.tsx
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:

Good to know: useSearchParams is 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.

pages/dashboard.tsx
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:

pages/dashboard.tsx
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:

pages/dashboard.tsx
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:

components/search-bar.tsx
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

VersionChanges
v13.0.0useSearchParams introduced.

Was this helpful?

supported.