mirror of
https://github.com/hanzoai/next.js.git
synced 2026-09-24 17:00:51 +00:00
c2b4c0815c
This PRs unifies the caching story across the docs, making Cache Components the happy path, while still providing guidance to users in the old model. However, instead of explaining the old model and its caching layers, we've created a new guide focusing on what APIs to use and when. This follow-up PR aligns terminology across the docs: https://github.com/vercel/next.js/pull/90589 ## IA updates Getting Started section: - Improves Getting Started progression: - **Before:** CC → Fetching Data → Updating Data → Caching and Revalidating (old and new model mixed) - **After:** Fetching Data (Dynamic) → Mutating Data (Dynamic) → Caching with CC (Prerendering) → Revalidating with CC. - New: `caching.mdx` (CC-first) - Structure: - Enabling Cache Components - Data vs UI-level caching - Working with request time APIs - Passing request values to cached functions - Working with non-deterministic operations - Working with synchronous operations - How rendering works (PPR and static shell story) - New: `revalidating.mdx` (CC-first) - Explains how to use `cacheLife` and `cacheTag` Guides Section: - New: `caching-and-revalidating.mdx` (Previous Model) - For users who are not using CC, includes `fetch` options and route segment config - Moves route segment config options that don't apply to CC from API reference to this guide (for easy archiving in the future). - New: `migrating-to-cache-components.mdx` (WIP) - Del: `caching.mdx` 😌 ## Terminology We should remove caching layers from the docs. Users only needed to be exposed to them when they were configured independently, but the new CC APIs work across layers. To make it easier to review this PR, I'm consolidating terminology and fixing broken links in a new PR: https://github.com/vercel/next.js/pull/90589 --------- Co-authored-by: Vercel <vercel[bot]@users.noreply.github.com> Co-authored-by: Joseph <[email protected]>
319 lines
9.9 KiB
Plaintext
319 lines
9.9 KiB
Plaintext
---
|
|
title: useSearchParams
|
|
description: API Reference for the useSearchParams hook in the Pages Router.
|
|
---
|
|
|
|
`useSearchParams` is a hook that lets you read the current URL's **query string**.
|
|
|
|
`useSearchParams` returns a **read-only** version of the [`URLSearchParams`](https://developer.mozilla.org/docs/Web/API/URLSearchParams) interface.
|
|
|
|
```tsx filename="pages/dashboard.tsx" switcher
|
|
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}</>
|
|
}
|
|
```
|
|
|
|
```jsx filename="pages/dashboard.js" switcher
|
|
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
|
|
|
|
```tsx
|
|
const searchParams = useSearchParams()
|
|
```
|
|
|
|
`useSearchParams` does not take any parameters.
|
|
|
|
## Returns
|
|
|
|
`useSearchParams` returns a **read-only** version of the [`URLSearchParams`](https://developer.mozilla.org/docs/Web/API/URLSearchParams) interface, or `null` during [prerendering](#behavior-during-prerendering).
|
|
|
|
The interface includes utility methods for reading the URL's query string:
|
|
|
|
- [`URLSearchParams.get()`](https://developer.mozilla.org/docs/Web/API/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'` _- use [`getAll()`](https://developer.mozilla.org/docs/Web/API/URLSearchParams/getAll) to get all values_ |
|
|
|
|
- [`URLSearchParams.has()`](https://developer.mozilla.org/docs/Web/API/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`](https://developer.mozilla.org/docs/Web/API/URLSearchParams), including the [`getAll()`](https://developer.mozilla.org/docs/Web/API/URLSearchParams/getAll), [`keys()`](https://developer.mozilla.org/docs/Web/API/URLSearchParams/keys), [`values()`](https://developer.mozilla.org/docs/Web/API/URLSearchParams/values), [`entries()`](https://developer.mozilla.org/docs/Web/API/URLSearchParams/entries), [`forEach()`](https://developer.mozilla.org/docs/Web/API/URLSearchParams/forEach), and [`toString()`](https://developer.mozilla.org/docs/Web/API/URLSearchParams/toString).
|
|
|
|
> **Good to know**: `useSearchParams` is a [React Hook](https://react.dev/learn#using-hooks) and cannot be used with classes.
|
|
|
|
## Behavior
|
|
|
|
### Behavior during prerendering
|
|
|
|
For pages that are [statically optimized](/docs/pages/building-your-application/rendering/automatic-static-optimization) (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.
|
|
|
|
```tsx filename="pages/dashboard.tsx" switcher
|
|
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}</>
|
|
}
|
|
```
|
|
|
|
```jsx filename="pages/dashboard.js" switcher
|
|
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`](/docs/pages/building-your-application/data-fetching/get-server-side-props), the page is server-rendered on each request and `useSearchParams` will return the actual search params immediately:
|
|
|
|
```tsx filename="pages/dashboard.tsx" switcher
|
|
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: {} }
|
|
}
|
|
```
|
|
|
|
```jsx filename="pages/dashboard.js" switcher
|
|
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`](/docs/pages/api-reference/functions/use-router) hook to update search params:
|
|
|
|
```tsx filename="pages/dashboard.tsx" switcher
|
|
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>
|
|
</>
|
|
)
|
|
}
|
|
```
|
|
|
|
```jsx filename="pages/dashboard.js" switcher
|
|
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
|
|
|
|
`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:
|
|
|
|
```tsx filename="components/search-bar.tsx" switcher
|
|
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..." />
|
|
}
|
|
```
|
|
|
|
```jsx filename="components/search-bar.js" switcher
|
|
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](/docs/app/api-reference/functions/use-search-params#prerendering) support.
|
|
|
|
## Version History
|
|
|
|
| Version | Changes |
|
|
| --------- | ----------------------------- |
|
|
| `v13.0.0` | `useSearchParams` introduced. |
|