Files
0553b34542 doc: instant navs runtime story (#93204)
- changes getting started -> caching
- new guide for instant navs
- new guide for runtime-prefetching (most pending stuff is here)
- x-refs between docs
- App Shell mentions in other docs (ISR w/ CC)

---------

Co-authored-by: Aurora Scharff <[email protected]>
Co-authored-by: Aurora Scharff <[email protected]>
2026-06-09 21:46:59 +00:00

242 lines
8.6 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
title: page.js
description: API reference for the page.js file.
---
The `page` file allows you to define UI that is **unique** to a route. You can create a page by default exporting a component from the file:
```tsx filename="app/blog/[slug]/page.tsx" switcher
export default function Page({
params,
searchParams,
}: {
params: Promise<{ slug: string }>
searchParams: Promise<{ [key: string]: string | string[] | undefined }>
}) {
return <h1>My Page</h1>
}
```
```jsx filename="app/blog/[slug]/page.js" switcher
export default function Page({ params, searchParams }) {
return <h1>My Page</h1>
}
```
## Good to know
- The `.js`, `.jsx`, or `.tsx` file extensions can be used for `page`.
- A `page` is always the **leaf** of the route subtree.
- A `page` file is required to make a route segment **publicly accessible**.
- Pages are [Server Components](https://react.dev/reference/rsc/server-components) by default, but can be set to a [Client Component](https://react.dev/reference/rsc/use-client).
- In the [component hierarchy](/docs/app/getting-started/project-structure#component-hierarchy), `page.js` is the innermost file convention. It is wrapped by `loading.js` (Suspense boundary), `error.js` (error boundary), `template.js`, and `layout.js` in the same segment.
## Reference
### Props
#### `params` (optional)
A promise that resolves to an object containing the [dynamic route parameters](/docs/app/api-reference/file-conventions/dynamic-routes) from the root segment down to that page.
```tsx filename="app/shop/[slug]/page.tsx" switcher
export default async function Page({
params,
}: {
params: Promise<{ slug: string }>
}) {
const { slug } = await params
}
```
```jsx filename="app/shop/[slug]/page.js" switcher
export default async function Page({ params }) {
const { slug } = await params
}
```
| Example Route | URL | `params` |
| ------------------------------------ | ----------- | --------------------------------------- |
| `app/shop/[slug]/page.js` | `/shop/1` | `Promise<{ slug: '1' }>` |
| `app/shop/[category]/[item]/page.js` | `/shop/1/2` | `Promise<{ category: '1', item: '2' }>` |
| `app/shop/[...slug]/page.js` | `/shop/1/2` | `Promise<{ slug: ['1', '2'] }>` |
- Since the `params` prop is a promise, you must use `async/await` or React's [`use`](https://react.dev/reference/react/use) function to access the values.
- In version 14 and earlier, `params` was a synchronous prop. To help with backwards compatibility, you can still access it synchronously in Next.js 15, but this behavior will be deprecated in the future.
#### `searchParams` (optional)
A promise that resolves to an object containing the [search parameters](https://developer.mozilla.org/docs/Learn/Common_questions/What_is_a_URL#parameters) of the current URL. For example:
```tsx filename="app/shop/page.tsx" switcher
export default async function Page({
searchParams,
}: {
searchParams: Promise<{ [key: string]: string | string[] | undefined }>
}) {
const filters = (await searchParams).filters
}
```
```jsx filename="app/shop/page.js" switcher
export default async function Page({ searchParams }) {
const filters = (await searchParams).filters
}
```
Client Component **pages** can also access `searchParams` using React’s [`use`](https://react.dev/reference/react/use) hook:
```tsx filename="app/shop/page.tsx" switcher
'use client'
import { use } from 'react'
export default function Page({
searchParams,
}: {
searchParams: Promise<{ [key: string]: string | string[] | undefined }>
}) {
const filters = use(searchParams).filters
}
```
```jsx filename="app/page.jsx" switcher
'use client'
import { use } from 'react'
export default function Page({ searchParams }) {
const filters = use(searchParams).filters
}
```
| Example URL | `searchParams` |
| --------------- | ----------------------------- |
| `/shop?a=1` | `Promise<{ a: '1' }>` |
| `/shop?a=1&b=2` | `Promise<{ a: '1', b: '2' }>` |
| `/shop?a=1&a=2` | `Promise<{ a: ['1', '2'] }>` |
- Since the `searchParams` prop is a promise. You must use `async/await` or React's [`use`](https://react.dev/reference/react/use) function to access the values.
- In version 14 and earlier, `searchParams` was a synchronous prop. To help with backwards compatibility, you can still access it synchronously in Next.js 15, but this behavior will be deprecated in the future.
- `searchParams` is a **[Request-time API](/docs/app/glossary#request-time-apis)** whose values cannot be known ahead of time. Using it will opt the page into **[dynamic rendering](/docs/app/glossary#dynamic-rendering)** at request time.
- With [Cache Components](/docs/app/getting-started/caching), where you access `searchParams` in the component tree determines how much of the page can be prerendered. See [Maximizing the static shell](/docs/app/getting-started/caching#maximizing-the-static-shell).
- `searchParams` is a plain JavaScript object, not a `URLSearchParams` instance.
### Page Props Helper
You can type pages with `PageProps` to get strongly typed `params` and `searchParams` from the route literal. `PageProps` is a globally available helper.
```tsx filename="app/blog/[slug]/page.tsx"
export default async function Page(props: PageProps<'/blog/[slug]'>) {
const { slug } = await props.params
const query = await props.searchParams
return <h1>Blog Post: {slug}</h1>
}
```
> **Good to know**
>
> - Using a literal route (e.g. `'/blog/[slug]'`) enables autocomplete and strict keys for `params`.
> - Static routes resolve `params` to `{}`.
> - Types are generated during `next dev`, `next build`, or with `next typegen`.
> - After type generation, the `PageProps` helper is globally available. It doesn't need to be imported.
## Examples
### Displaying content based on `params`
Using [dynamic route segments](/docs/app/api-reference/file-conventions/dynamic-routes), you can display or fetch specific content for the page based on the `params` prop.
```tsx filename="app/blog/[slug]/page.tsx" switcher
export default async function Page({
params,
}: {
params: Promise<{ slug: string }>
}) {
const { slug } = await params
return <h1>Blog Post: {slug}</h1>
}
```
```jsx filename="app/blog/[slug]/page.js" switcher
export default async function Page({ params }) {
const { slug } = await params
return <h1>Blog Post: {slug}</h1>
}
```
### Handling filtering with `searchParams`
You can use the `searchParams` prop to handle filtering, pagination, or sorting based on the query string of the URL.
```tsx filename="app/shop/page.tsx" switcher
export default async function Page({
searchParams,
}: {
searchParams: Promise<{ [key: string]: string | string[] | undefined }>
}) {
const { page = '1', sort = 'asc', query = '' } = await searchParams
return (
<div>
<h1>Product Listing</h1>
<p>Search query: {query}</p>
<p>Current page: {page}</p>
<p>Sort order: {sort}</p>
</div>
)
}
```
```jsx filename="app/shop/page.js" switcher
export default async function Page({ searchParams }) {
const { page = '1', sort = 'asc', query = '' } = await searchParams
return (
<div>
<h1>Product Listing</h1>
<p>Search query: {query}</p>
<p>Current page: {page}</p>
<p>Sort order: {sort}</p>
</div>
)
}
```
### Reading `searchParams` and `params` in Client Components
To use `searchParams` and `params` in a Client Component (which cannot be `async`), you can use React's [`use`](https://react.dev/reference/react/use) function to read the promise:
```tsx filename="app/page.tsx" switcher
'use client'
import { use } from 'react'
export default function Page({
params,
searchParams,
}: {
params: Promise<{ slug: string }>
searchParams: Promise<{ [key: string]: string | string[] | undefined }>
}) {
const { slug } = use(params)
const { query } = use(searchParams)
}
```
```js filename="app/page.js" switcher
'use client'
import { use } from 'react'
export default function Page({ params, searchParams }) {
const { slug } = use(params)
const { query } = use(searchParams)
}
```
## Version History
| Version | Changes |
| ------------ | ---------------------------------------------------------------------------------------------------------------- |
| `v15.0.0-RC` | `params` and `searchParams` are now promises. A [codemod](/docs/app/guides/upgrading/codemods#150) is available. |
| `v13.0.0` | `page` introduced. |