Skip to content
Merged
34 changes: 34 additions & 0 deletions docs/01-app/01-getting-started/03-layouts-and-pages.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -324,3 +324,37 @@ export default async function Post({ post }) {
```

> **Good to know**: `<Link>` is the primary way to navigate between routes in Next.js. You can also use the [`useRouter` hook](/docs/app/api-reference/functions/use-router) for more advanced navigation.

## Route Props Helpers

Next.js exposes utility types that infer `params` and named slots from your route structure:

- [**PageProps**](/docs/app/api-reference/file-conventions/page#page-props-helper): Props for `page` components, including `params` and `searchParams`.
- [**LayoutProps**](/docs/app/api-reference/file-conventions/layout#layout-props-helper): Props for `layout` components, including `children` and any named slots (e.g. folders like `@analytics`).

These are globally available helpers, generated when running either `next dev`, `next build` or [`next typegen`](/docs/app/api-reference/cli/next#next-typegen-options).

```tsx filename="app/blog/[slug]/page.tsx"
export default async function Page(props: PageProps<'/blog/[slug]'>) {
const { slug } = await props.params
return <h1>Blog post: {slug}</h1>
}
```

```tsx filename="app/dashboard/layout.tsx"
export default function Layout(props: LayoutProps<'/dashboard'>) {
return (
<section>
{props.children}
{/* If you have app/dashboard/@analytics, it appears as a typed slot: */}
{/* {props.analytics} */}
</section>
)
}
```

> **Good to know**
>
> - Static routes resolve `params` to `{}`.
> - `PageProps`, `LayoutProps` are global helpers — no imports required.
> - Types are generated during `next dev`, `next build` or `next typegen`.
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,23 @@ export async function POST(request) {}

Read more about how Route Handlers [complement your frontend application](/docs/app/guides/backend-for-frontend), or explore the Route Handlers [API Reference](/docs/app/api-reference/file-conventions/route).

### Route Context Helper

In TypeScript, you can type the `context` parameter for Route Handlers with the globally available [`RouteContext`](/docs/app/api-reference/file-conventions/route#route-context-helper) helper:

```ts filename="app/users/[id]/route.ts" switcher
import type { NextRequest } from 'next/server'

export async function GET(_req: NextRequest, ctx: RouteContext<'/users/[id]'>) {
const { id } = await ctx.params
return Response.json({ id })
}
```

> **Good to know**
>
> - Types are generated during `next dev`, `next build` or `next typegen`.

## Middleware

Middleware allows you to run code before a request is completed. Then, based on the incoming request, you can modify the response by rewriting, redirecting, modifying the request or response headers, or responding directly.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ The difference between **catch-all** and **optional catch-all** segments is that

### TypeScript

When using TypeScript, you can add types for `params` depending on your configured route segment.
When using TypeScript, you can add types for `params` depending on your configured route segment — use [`PageProps<'/route'>`](/docs/app/api-reference/file-conventions/page#page-props-helper), [`LayoutProps<'/route'>`](/docs/app/api-reference/file-conventions/layout#layout-props-helper), or [`RouteContext<'/route'>`](/docs/app/api-reference/file-conventions/route#route-context-helper) to type `params` in `page`, `layout`, and `route` respectively.

| Route | `params` Type Definition |
| ----------------------------------- | ---------------------------------------- |
Expand Down
20 changes: 20 additions & 0 deletions docs/01-app/03-api-reference/03-file-conventions/layout.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,26 @@ export default async function Layout({ children, params }) {
- 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.

### Layout Props Helper

You can type layouts with `LayoutProps` to get a strongly typed `params` and named slots inferred from your directory structure. `LayoutProps` is a globally available helper.

```tsx filename="app/dashboard/layout.tsx" switcher
export default function Layout(props: LayoutProps<'/dashboard'>) {
return (
<section>
{props.children}
{/* If you have app/dashboard/@analytics, it appears as a typed slot: */}
{/* {props.analytics} */}
</section>
)
}
```

> **Good to know**:
>
> - Types are generated during `next dev`, `next build` or `next typegen`.

### Root Layout

The `app` directory **must** include a **root layout**, which is the top-most layout in the root `app` directory. Typically, the root layout is `app/layout.js`.
Expand Down
18 changes: 18 additions & 0 deletions docs/01-app/03-api-reference/03-file-conventions/page.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,24 @@ export default function Page({ searchParams }) {
- `searchParams` is a **[Dynamic API](/docs/app/getting-started/partial-prerendering#dynamic-rendering)** whose values cannot be known ahead of time. Using it will opt the page into **[dynamic rendering](/docs/app/getting-started/partial-prerendering#dynamic-rendering)** at request time.
- `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" switcher
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`.

## Examples

### Displaying content based on `params`
Expand Down
17 changes: 17 additions & 0 deletions docs/01-app/03-api-reference/03-file-conventions/route.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,23 @@ export async function GET(request, { params }) {
| `app/shop/[tag]/[item]/route.js` | `/shop/1/2` | `Promise<{ tag: '1', item: '2' }>` |
| `app/blog/[...slug]/route.js` | `/blog/1/2` | `Promise<{ slug: ['1', '2'] }>` |

### Route Context Helper

You can type the Route Handler context using `RouteContext` to get strongly typed `params` from a route literal. `RouteContext` is a globally available helper.

```ts filename="app/users/[id]/route.ts" switcher
import type { NextRequest } from 'next/server'

export async function GET(_req: NextRequest, ctx: RouteContext<'/users/[id]'>) {
const { id } = await ctx.params
return Response.json({ id })
}
```

> **Good to know**
>
> - Types are generated during `next dev`, `next build` or `next typegen`.

## Examples

### Cookies
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ export async function generateMetadata({ params, searchParams }, parent) {
export default function Page({ params, searchParams }) {}
```

For type completion of `params` and `searchParams`, you can type the first argument with [`PageProps<'/route'>`](/docs/app/api-reference/file-conventions/page#page-props-helper) or [`LayoutProps<'/route'>`](/docs/app/api-reference/file-conventions/layout#layout-props-helper) for pages and layouts respectively.

> **Good to know**:
>
> - Metadata can be added to `layout.js` and `page.js` files.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,26 @@ export default function Page({ params }) {
}
```

Notice that the params argument can be accessed synchronously and includes only parent segment params.

For type completion, you can make use of the TypeScript `Awaited` helper in combination with either [`Page Props helper`](/docs/app/api-reference/file-conventions/page#page-props-helper) or [`Layout Props helper`](/docs/app/api-reference/file-conventions/layout#layout-props-helper):

```ts filename="app/products/[category]/[product]/page.tsx" switcher
export async function generateStaticParams({
params: { category },
}: {
params: Awaited<LayoutProps<'/products/[category]'>['params']>
}) {
const products = await fetch(
`https://.../products?category=${category}`
).then((res) => res.json())

return products.map((product) => ({
product: product.id,
}))
}
```

> **Good to know**: `fetch` requests are automatically [memoized](/docs/app/guides/caching#request-memoization) for the same data across all `generate`-prefixed functions, Layouts, Pages, and Server Components. React [`cache` can be used](/docs/app/guides/caching#react-cache-function) if `fetch` is unavailable.

## Version History
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ export function generateViewport({ params }) {
}
```

In TypeScript, the `params` argument can be typed via [`PageProps<'/route'>`](/docs/app/api-reference/file-conventions/page#page-props-helper) or [`LayoutProps<'/route'>`](/docs/app/api-reference/file-conventions/layout#layout-props-helper) depending on where `generateViewport` is defined.

```jsx filename="layout.js | page.js" switcher
export function generateViewport({ params }) {
return {
Expand Down
30 changes: 30 additions & 0 deletions docs/01-app/03-api-reference/05-config/02-typescript.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,14 @@ export default async function Page() {

For _complete_ end-to-end type safety, this also requires your database or content provider to support TypeScript. This could be through using an [ORM](https://en.wikipedia.org/wiki/Object%E2%80%93relational_mapping) or type-safe query builder.

## Route-Aware Type Helpers

Next.js generates global helpers for App Router route types. These are available without imports and are generated during `next dev`, `next build`, or via [`next typegen`](/docs/app/api-reference/cli/next#next-typegen-options):

- [`PageProps`](/docs/app/api-reference/file-conventions/page#page-props-helper)
- [`LayoutProps`](/docs/app/api-reference/file-conventions/layout#layout-props-helper)
- [`RouteContext`](/docs/app/api-reference/file-conventions/route#route-context-helper)

</AppOnly>

## Examples
Expand Down Expand Up @@ -139,6 +147,28 @@ import Link from 'next/link'
<Link href="/aboot" />
```

The same applies for redirecting routes defined by middleware:

```ts filename="middleware.ts"
import { NextRequest, NextResponse } from 'next/server'

export function middleware(request: NextRequest) {
if (request.nextUrl.pathname === '/middleware-redirect') {
return NextResponse.redirect(new URL('/', request.url))
}

return NextResponse.next()
}
```

```tsx filename="app/some/page.tsx"
import type { Route } from 'next'

export default function Page() {
return <Link href={'/middleware-redirect' as Route}>Link Text</Link>
}
```

To accept `href` in a custom component wrapping `next/link`, use a generic:

```tsx
Expand Down
33 changes: 33 additions & 0 deletions docs/01-app/03-api-reference/06-cli/next.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ The following commands are available:
| [`info`](#next-info-options) | Prints relevant details about the current system which can be used to report Next.js bugs. |
| [`lint`](#next-lint-options) | Runs ESLint for all files in the `/src`, `/app`, `/pages`, `/components`, and `/lib` directories. It also provides a guided setup to install any required dependencies if ESLint it is not already configured in your application. |
| [`telemetry`](#next-telemetry-options) | Allows you to enable or disable Next.js' completely anonymous telemetry collection. |
| [`typegen`](#next-typegen-options) | Generates TypeScript definitions for routes, pages, layouts, and route handlers without running a full build. |

> **Good to know**: Running `next` without a command is an alias for `next dev`.

Expand Down Expand Up @@ -138,6 +139,8 @@ The following options are available for the `next info` command:

### `next lint` options

> **Warning**: This option is deprecated and will be removed in Next 16. A [codemod](/blog/next-15-5#next-lint-deprecation) is available to migrate to ESLint CLI.

`next lint` runs ESLint for all files in the `pages/`, `app/`, `components/`, `lib/`, and `src/` directories. It also provides a guided setup to install any required dependencies if ESLint is not already configured in your application.

The following options are available for the `next lint` command:
Expand Down Expand Up @@ -182,6 +185,35 @@ The following options are available for the `next telemetry` command:

Learn more about [Telemetry](/telemetry).

### `next typegen` Options

`next typegen` generates TypeScript definitions for your application's routes without performing a full build. This is useful for IDE autocomplete and CI type-checking of route usage.

Previously, route types were only generated during `next dev` or `next build`, which meant running `tsc --noEmit` directly wouldn't validate your route types. Now you can generate types independently and validate them externally:

```bash filename="Terminal"
# Generate route types first, then validate with TypeScript
next typegen && tsc --noEmit

# Or in CI workflows for type checking without building
next typegen && npm run type-check
```

The following options are available for the `next typegen` command:

| Option | Description |
| ------------- | -------------------------------------------------------------------------------------------- |
| `-h, --help` | Show all available options. |
| `[directory]` | A directory on which to generate types. If not provided, the current directory will be used. |

Output files are written to `<distDir>/types` (default: `.next/types`):

```bash filename="Terminal"
next typegen
# or for a specific app
next typegen ./apps/web
```

## Examples

### Debugging prerender errors
Expand Down Expand Up @@ -264,4 +296,5 @@ NODE_OPTIONS='--inspect' next

| Version | Changes |
| --------- | ------------------------------------------------------------------------------- |
| `v15.5.0` | Add the `next typegen` command |
| `v15.4.0` | Add `--debug-prerender` option for `next build` to help debug prerender errors. |
2 changes: 1 addition & 1 deletion docs/02-pages/02-guides/amp.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ description: With minimal config, and without leaving React, you can start addin

</details>

> **Warning**: Built-in amp support will be removed in Next.js 16.
> **Warning**: Built-in AMP support will be removed in Next.js 16.

With Next.js you can turn any React page into an AMP page, with minimal config, and without leaving React.

Expand Down
2 changes: 1 addition & 1 deletion docs/02-pages/04-api-reference/03-functions/use-amp.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ description: Enable AMP in a page, and control the way Next.js adds AMP to the p

</details>

> AMP support is one of our advanced features, you can [read more about AMP here](/docs/pages/guides/amp).
> **Warning**: Built-in AMP support will be removed in Next.js 16.

To enable AMP, add the following config to your page:

Expand Down
Loading