Docs IA 2.0: Delete routing section, add BFF guide, polish getting started (#80365)

Closes:
https://linear.app/vercel/issue/DOC-4686/clean-up-routing-section
Redirects: https://github.com/vercel/front/pull/47151

---------

Co-authored-by: Joseph <[email protected]>
Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
This commit is contained in:
Delba de Oliveira
2025-06-16 13:42:20 +01:00
committed by GitHub
co-authored by Joseph graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
parent 27fed1c1b6
commit 2e2ee08b60
177 changed files with 952 additions and 176 deletions
@@ -22,7 +22,7 @@ Top-level folders are used to organize your application's code and static assets
| | |
| ------------------------------------------------------------------ | ---------------------------------- |
| [`app`](/docs/app/building-your-application/routing) | App Router |
| [`app`](/docs/app) | App Router |
| [`pages`](/docs/pages/building-your-application/routing) | Pages Router |
| [`public`](/docs/app/api-reference/file-conventions/public-folder) | Static assets to be served |
| [`src`](/docs/app/api-reference/file-conventions/src-folder) | Optional application source folder |
@@ -1,5 +1,5 @@
---
title: Fetching Data and Streaming
title: Fetching Data
description: Learn how to fetch data and stream content that depends on data.
related:
title: API Reference
@@ -396,7 +396,7 @@ In development, you can preview and inspect the loading state of your components
### Sequential data fetching
Sequential data fetching happens when nested components in a tree each fetch their own data and the requests are not [deduplicated](/docs/app/deep-dive/caching#request-memoization), leading to longer response times.
Sequential data fetching happens when nested components in a tree each fetch their own data and the requests are not [deduplicated](/docs/app/guides/caching#request-memoization), leading to longer response times.
<Image
alt="Sequential and Parallel Data Fetching"
@@ -1,5 +1,5 @@
---
title: Updating data
title: Updating Data
description: Learn how to mutate data using Server Functions.
related:
title: API Reference
@@ -23,7 +23,7 @@ By convention, a Server Action is an async function used with [`startTransition`
- Passed to a `<form>` using the `action` prop.
- Passed to a `<button>` using the `formAction` prop.
In Next.js, Server Actions integrate with the framework's [caching](/docs/app/deep-dive/caching) architecture. When an action is invoked, Next.js can return both the updated UI and new data in a single server roundtrip.
In Next.js, Server Actions integrate with the framework's [caching](/docs/app/guides/caching) architecture. When an action is invoked, Next.js can return both the updated UI and new data in a single server roundtrip.
Behind the scenes, actions use the `POST` method, and only this HTTP method can invoke them.
+1 -1
View File
@@ -10,7 +10,7 @@ related:
- app/guides/css-in-js
---
Next.js provides several ways to use CSS in your application, including:
Next.js provides several ways to style your application using CSS, including:
- [CSS Modules](#css-modules)
- [Global CSS](#global-css)
@@ -1,13 +1,18 @@
---
title: Route Handlers
description: Create custom request handlers for a given route using the Web's Request and Response APIs.
title: Route Handlers and Middleware
nav_title: Route Handlers and Middleware
description: Learn how to use Route Handlers and Middleware
related:
title: API Reference
description: Learn more about the route.js file.
description: Learn more about Route Handlers and Middleware
links:
- app/api-reference/file-conventions/route
- app/api-reference/file-conventions/middleware
- app/guides/backend-for-frontend
---
## Route Handlers
Route Handlers allow you to create custom request handlers for a given route using the Web [Request](https://developer.mozilla.org/docs/Web/API/Request) and [Response](https://developer.mozilla.org/docs/Web/API/Response) APIs.
<Image
@@ -20,7 +25,7 @@ Route Handlers allow you to create custom request handlers for a given route usi
> **Good to know**: Route Handlers are only available inside the `app` directory. They are the equivalent of [API Routes](/docs/pages/building-your-application/routing/api-routes) inside the `pages` directory meaning you **do not** need to use API Routes and Route Handlers together.
## Convention
### Convention
Route Handlers are defined in a [`route.js|ts` file](/docs/app/api-reference/file-conventions/route) inside the `app` directory:
@@ -42,8 +47,6 @@ The following [HTTP methods](https://developer.mozilla.org/docs/Web/HTTP/Methods
In addition to supporting the native [Request](https://developer.mozilla.org/docs/Web/API/Request) and [Response](https://developer.mozilla.org/docs/Web/API/Response) APIs, Next.js extends them with [`NextRequest`](/docs/app/api-reference/functions/next-request) and [`NextResponse`](/docs/app/api-reference/functions/next-response) to provide convenient helpers for advanced use cases.
## Behavior
### Caching
Route Handlers are not cached by default. You can, however, opt into caching for `GET` methods. Other supported HTTP methods are **not** cached. To cache a `GET` method, use a [route config option](/docs/app/api-reference/file-conventions/route-segment-config#dynamic) such as `export const dynamic = 'force-static'` in your Route Handler file.
@@ -120,3 +123,63 @@ export default function Page() {
// `app/route.js`
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).
## 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.
### Use cases
Some common scenarios where Middleware is effective include:
- Quick redirects after reading parts of the incoming request
- Rewriting to different pages based on A/B tests or experiments
- Modifying headers for all pages or a subset of pages
Middleware is _not_ a good fit for:
- Slow data fetching
- Session management
Using fetch with `options.cache`, `options.next.revalidate`, or `options.next.tags`, has no effect in Middleware.
### Convention
Use the file `middleware.ts` (or `.js`) in the root of your project to define Middleware. For example, at the same level as `pages` or `app`, or inside `src` if applicable.
> **Note**: While only one `middleware.ts` file is supported per project, you can still organize your middleware logic into modules. Break out middleware functionalities into separate `.ts` or `.js` files and import them into your main `middleware.ts` file. This allows for cleaner management of route-specific middleware, aggregated in the `middleware.ts` for centralized control. By enforcing a single middleware file, it simplifies configuration, prevents potential conflicts, and optimizes performance by avoiding multiple middleware layers.
### Example
```ts filename="middleware.ts" switcher
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
// This function can be marked `async` if using `await` inside
export function middleware(request: NextRequest) {
return NextResponse.redirect(new URL('/home', request.url))
}
// See "Matching Paths" below to learn more
export const config = {
matcher: '/about/:path*',
}
```
```js filename="middleware.js" switcher
import { NextResponse } from 'next/server'
// This function can be marked `async` if using `await` inside
export function middleware(request) {
return NextResponse.redirect(new URL('/home', request.url))
}
// See "Matching Paths" below to learn more
export const config = {
matcher: '/about/:path*',
}
```
Read more about [using `middleware`](/docs/app/guides/backend-for-frontend#middleware), or refer to the `middleware` [API reference](/docs/app/api-reference/file-conventions/middleware).
+1 -1
View File
@@ -1443,7 +1443,7 @@ export async function serverAction() {
### Route Handlers
Treat [Route Handlers](/docs/app/building-your-application/routing/route-handlers) with the same security considerations as public-facing API endpoints, and verify if the user is allowed to access the Route Handler.
Treat [Route Handlers](/docs/app/api-reference/file-conventions/route) with the same security considerations as public-facing API endpoints, and verify if the user is allowed to access the Route Handler.
For example:
@@ -0,0 +1,792 @@
---
title: How to use Next.js as a backend for your frontend
nav_title: Backend for Frontend
description: Learn how to use Next.js as a backend framework
related:
title: API Reference
description: Learn more about Route Handlers and Middleware
links:
- app/api-reference/file-conventions/route
- app/api-reference/file-conventions/middleware
---
Next.js supports the "Backend for Frontend" pattern. This lets you create public endpoints to handle HTTP requests and return any content type—not just HTML. You can also access data sources and perform side effects like updating remote data.
If you are starting a new project, using `create-next-app` with the `--api` flag automatically includes an example `route.ts` in your new project’s `app/` folder, demonstrating how to create an API endpoint.
```bash filename="Terminal"
npx create-next-app@latest --api
```
> **Good to know**: Next.js backend capabilities are not a full backend replacement. They serve as an API layer that:
>
> - is publicly reachable
> - handles any HTTP request
> - can return any content type
To implement this pattern, use:
- [Route Handlers](/docs/app/api-reference/file-conventions/route)
- [`middleware`](/docs/app/api-reference/file-conventions/middleware)
- In Pages Router, [API Routes](/pages/building-your-application/routing/api-routes)
## Public Endpoints
Route Handlers are public HTTP endpoints. Any client can access them.
Create a Route Handler using the `route.ts` or `route.js` file convention:
```ts filename="/app/api/route.ts" switcher
export function GET(request: Request) {}
```
```js filename="/app/api/route.js" switcher
export function GET(request) {}
```
This handles `GET` requests sent to `/api`.
Use `try/catch` blocks for operations that may throw an exception:
```ts filename="/app/api/route.ts" switcher
import { submit } from '@/lib/submit'
export function POST(request: Request) {
try {
await submit(request)
return new Response(null, { status: 204 })
} catch (reason) {
const message =
reason instanceof Error ? reason.message : 'Unexpected error'
return new Response(message, { status: 500 })
}
}
```
```js filename="/app/api/route.js" switcher
import { submit } from '@/lib/submit'
export function POST(request) {
try {
await submit(request)
return new Response(null, { status: 204 })
} catch (reason) {
const message =
reason instanceof Error ? reason.message : 'Unexpected error'
return new Response(message, { status: 500 })
}
}
```
Avoid exposing sensitive information in error messages sent to the client.
To restrict access, implement authentication and authorization. See [Authentication](/docs/app/guides/authentication).
## Content types
Route Handlers let you serve non-UI responses, including JSON, XML, images, files, and plain text.
Next.js uses file conventions for common endpoints:
- [`sitemap.xml`](/docs/app/api-reference/file-conventions/metadata/sitemap)
- [`opengraph-image.jpg`, `twitter-image`](/docs/app/api-reference/file-conventions/metadata/opengraph-image)
- [favicon, app icon, and apple-icon](/docs/app/api-reference/file-conventions/metadata/app-icons)
- [`manifest.json`](/docs/app/api-reference/file-conventions/metadata/manifest)
- [`robots.txt`](/docs/app/api-reference/file-conventions/metadata/robots)
You can also define custom ones, such as:
- `llms.txt`
- `rss.xml`
- `.well-known`
For example, `app/rss.xml/route.ts` creates a Route Handler for `rss.xml`.
```ts filename="/app/rss.xml/route.ts" switcher
export async function GET(request: Request) {
const rssResponse = await fetch(/* rss endpoint */)
const rssData = await rssResponse.json()
const rssFeed = `<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
<channel>
<title>${rssData.title}</title>
<description>${rssData.description}</description>
<link>${rssData.link}</link>
<copyright>${rssData.copyright}</copyright>
${rssData.items.map((item) => {
return `<item>
<title>${item.title}</title>
<description>${item.description}</description>
<link>${item.link}</link>
<pubDate>${item.publishDate}</pubDate>
<guid isPermaLink="false">${item.guid}</guid>
</item>`
})}
</channel>
</rss>`
const headers = new Headers({ 'content-type': 'application/xml' })
return new Response(rssFeed, { headers })
}
```
```js filename="/app/rss.xml/route.js" switcher
export async function GET(request) {
const rssResponse = await fetch(/* rss endpoint */)
const rssData = await rssResponse.json()
const rssFeed = `<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
<channel>
<title>${rssData.title}</title>
<description>${rssData.description}</description>
<link>${rssData.link}</link>
<copyright>${rssData.copyright}</copyright>
${rssData.items.map((item) => {
return `<item>
<title>${item.title}</title>
<description>${item.description}</description>
<link>${item.link}</link>
<pubDate>${item.publishDate}</pubDate>
<guid isPermaLink="false">${item.guid}</guid>
</item>`
})}
</channel>
</rss>`
const headers = new Headers({ 'content-type': 'application/xml' })
return new Response(rssFeed, { headers })
}
```
Sanitize any input used to generate markup.
### Consuming request payloads
Use Request [instance methods](https://developer.mozilla.org/en-US/docs/Web/API/Request#instance_methods) like `.json()`, `.formData()`, or `.text()` to access the request body.
`GET` and `HEAD` requests don’t carry a body.
```ts filename="/app/api/echo-body/route.ts" switcher
export async function POST(request: Request) {
const res = await request.json()
return Response.json({ res })
}
```
```js filename="/app/api/echo-body/route.js" switcher
export async function POST(request) {
const res = await request.json()
return Response.json({ res })
}
```
> **Good to know**: Validate data before passing it to other systems
```ts filename="/app/api/send-email/route.ts" switcher
import { sendMail, validateInputs } from '@/lib/email-transporter'
export async function POST(request: Request) {
const formData = await request.formData()
const email = formData.get('email')
const contents = formData.get('contents')
try {
await validateInputs({ email, contents })
const info = await sendMail({ email, contents })
return Response.json({ messageId: info.messageId })
} catch (reason) {
const message =
reason instanceof Error ? reason.message : 'Unexpected exception'
return new Response(message, { status: 500 })
}
}
```
```js filename="/app/api/send-email/route.js" switcher
import { sendMail, validateInputs } from '@/lib/email-transporter'
export async function POST(request) {
const formData = await request.formData()
const email = formData.get('email')
const contents = formData.get('contents')
try {
await validateInputs({ email, contents })
const info = await sendMail({ email, contents })
return Response.json({ messageId: info.messageId })
} catch (reason) {
const message =
reason instanceof Error ? reason.message : 'Unexpected exception'
return new Response(message, { status: 500 })
}
}
```
You can only read the request body once. Clone the request if you need to read it again:
```ts filename="/app/api/clone/route.ts" switcher
export async function POST(request: Request) {
try {
const clonedRequest = request.clone()
await request.body()
await clonedRequest.body()
await request.body() // Throws error
return new Response(null, { status: 204 })
} catch {
return new Response(null, { status: 500 })
}
}
```
```js filename="/app/api/clone/route.js" switcher
export async function POST(request) {
try {
const clonedRequest = request.clone()
await request.body()
await clonedRequest.body()
await request.body() // Throws error
return new Response(null, { status: 204 })
} catch {
return new Response(null, { status: 500 })
}
}
```
## Manipulating data
Route Handlers can transform, filter, and aggregate data from one or more sources. This keeps logic out of the frontend and avoids exposing internal systems.
You can also offload heavy computations to the server and reduce client battery and data usage.
```ts file="/app/api/weather/route.ts" switcher
import { parseWeatherData } from '@/lib/weather'
export async function POST(request: Request) {
const body = await request.json()
const searchParams = new URLSearchParams({ lat: body.lat, lng: body.lng })
try {
const weatherResponse = await fetch(`${weatherEndpoint}?${searchParams}`)
if (!weatherResponse.ok) {
/* handle error */
}
const weatherData = await weatherResponse.text()
const payload = parseWeatherData.asJSON(weatherData)
return new Response(payload, { status: 200 })
} catch (reason) {
const message =
reason instanceof Error ? reason.message : 'Unexpected exception'
return new Response(message, { status: 500 })
}
}
```
```js file="/app/api/weather/route.js" switcher
import { parseWeatherData } from '@/lib/weather'
export async function POST(request) {
const body = await request.json()
const searchParams = new URLSearchParams({ lat: body.lat, lng: body.lng })
try {
const weatherResponse = await fetch(`${weatherEndpoint}?${searchParams}`)
if (!weatherResponse.ok) {
/* handle error */
}
const weatherData = await weatherResponse.text()
const payload = parseWeatherData.asJSON(weatherData)
return new Response(payload, { status: 200 })
} catch (reason) {
const message =
reason instanceof Error ? reason.message : 'Unexpected exception'
return new Response(message, { status: 500 })
}
}
```
> **Good to know**: This example uses `POST` to avoid putting geo-location data in the URL. `GET` requests may be cached or logged, which could expose sensitive info.
## Proxying to a backend
You can use a Route Handler as a proxy to another backend. Add validation logic before forwarding the request.
```ts filename="/app/api/[...slug]/route.ts" switcher
import { isValidRequest } from '@/lib/utils'
export async function POST(request: Request, { params }) {
const clonedRequest = request.clone()
const isValid = await isValidRequest(clonedRequest)
if (!isValid) {
return new Response(null, { status: 400, statusText: 'Bad Request' })
}
const { slug } = await params
const pathname = slug.join('/')
const proxyURL = new URL(pathname, 'https://nextjs.org')
const proxyRequest = new Request(proxyURL, request)
try {
return fetch(proxyRequest)
} catch (reason) {
const message =
reason instanceof Error ? reason.message : 'Unexpected exception'
return new Response(message, { status: 500 })
}
}
```
```js filename="/app/api/[...slug]/route.js" switcher
import { isValidRequest } from '@/lib/utils'
export async function POST(request, { params }) {
const clonedRequest = request.clone()
const isValid = await isValidRequest(clonedRequest)
if (!isValid) {
return new Response(null, { status: 400, statusText: 'Bad Request' })
}
const { slug } = await params
const pathname = slug.join('/')
const proxyURL = new URL(pathname, 'https://nextjs.org')
const proxyRequest = new Request(proxyURL, request)
try {
return fetch(proxyRequest)
} catch (reason) {
const message =
reason instanceof Error ? reason.message : 'Unexpected exception'
return new Response(message, { status: 500 })
}
}
```
Or use:
- `middleware` [rewrites](#middleware)
- [`rewrites`](/docs/app/api-reference/config/next-config-js/rewrites) in `next.config.js`.
## NextRequest and NextResponse
Next.js extends the [`Request`](https://developer.mozilla.org/en-US/docs/Web/API/Request) and [`Response`](https://developer.mozilla.org/en-US/docs/Web/API/Response) Web APIs with methods that simplify common operations. These extensions are available in both Route Handlers and Middleware.
Both provide methods for reading and manipulating cookies.
`NextRequest` includes the [`nextUrl`](/docs/app/api-reference/functions/next-request#nexturl) property, which exposes parsed values from the incoming request, for example, it makes it easier to access request pathname and search params.
`NextResponse` provides helpers like `next()`, `json()`, `redirect()`, and `rewrite()`.
You can pass `NextRequest` to any function expecting `Request`. Likewise, you can return `NextResponse` where a `Response` is expected.
```ts filename="/app/echo-pathname/route.ts" switcher
import { type NextRequest, NextResponse } from 'next/server'
export async function GET(request: NextRequest) {
const nextUrl = request.nextUrl
if (nextUrl.searchParams.get('redirect')) {
return NextResponse.redirect(new URL('/', request.url))
}
if (nextUrl.searchParams.get('rewrite')) {
return NextResponse.rewrite(new URL('/', request.url))
}
return NextResponse.json({ pathname: nextUrl.pathname })
}
```
```js filename="/app/echo-pathname/route.js" switcher
import { NextResponse } from 'next/server'
export async function GET(request) {
const nextUrl = request.nextUrl
if (nextUrl.searchParams.get('redirect')) {
return NextResponse.redirect(new URL('/', request.url))
}
if (nextUrl.searchParams.get('rewrite')) {
return NextResponse.rewrite(new URL('/', request.url))
}
return NextResponse.json({ pathname: nextUrl.pathname })
}
```
Learn more about [`NextRequest`](/docs/app/api-reference/functions/next-request) and [`NextResponse`](/docs/app/api-reference/functions/next-response).
## Webhooks and callback URLs
Use Route Handlers to receive event notifications from third-party applications.
For example, revalidate a route when content changes in a CMS. Configure the CMS to call a specific endpoint on changes.
```ts filename="/app/webhook/route.ts" switcher
import { type NextRequest, NextResponse } from 'next/server'
export async function GET(request: NextRequest) {
const token = request.nextUrl.searchParams.get('token')
if (token !== process.env.REVALIDATE_SECRET_TOKEN) {
return NextResponse.json({ success: false }, { status: 401 })
}
const tag = request.nextUrl.searchParams.get('tag')
if (!tag) {
return NextResponse.json({ success: false }, { status: 400 })
}
revalidateTag(tag)
return NextResponse.json({ success: true })
}
```
```js filename="/app/webhook/route.js" switcher
import { NextResponse } from 'next/server'
export async function GET(request) {
const token = request.nextUrl.searchParams.get('token')
if (token !== process.env.REVALIDATE_SECRET_TOKEN) {
return NextResponse.json({ success: false }, { status: 401 })
}
const tag = request.nextUrl.searchParams.get('tag')
if (!tag) {
return NextResponse.json({ success: false }, { status: 400 })
}
revalidateTag(tag)
return NextResponse.json({ success: true })
}
```
Callback URLs are another use case. When a user completes a third-party flow, the third party sends them to a callback URL. Use a Route Handler to verify the response and decide where to redirect the user.
```ts filename="/app/auth/callback/route.ts" switcher
import { type NextRequest, NextResponse } from 'next/server'
export async function GET(request: NextRequest) {
const token = request.nextUrl.searchParams.get('session_token')
const redirectUrl = request.nextUrl.searchParams.get('redirect_url')
const response = NextResponse.redirect(new URL(redirectUrl, request.url))
response.cookies.set({
value: token,
name: '_token',
path: '/',
secure: true,
httpOnly: true,
expires: undefined, // session cookie
})
return response
}
```
```js filename="/app/auth/callback/route.js" switcher
import { NextResponse } from 'next/server'
export async function GET(request) {
const token = request.nextUrl.searchParams.get('session_token')
const redirectUrl = request.nextUrl.searchParams.get('redirect_url')
const response = NextResponse.redirect(new URL(redirectUrl, request.url))
response.cookies.set({
value: token,
name: '_token',
path: '/',
secure: true,
httpOnly: true,
expires: undefined, // session cookie
})
return response
}
```
## Redirects
```ts filename="app/api/route.ts" switcher
import { redirect } from 'next/navigation'
export async function GET(request: Request) {
redirect('https://nextjs.org/')
}
```
```js filename="app/api/route.js" switcher
import { redirect } from 'next/navigation'
export async function GET(request) {
redirect('https://nextjs.org/')
}
```
Learn more about redirects in [`redirect`](/docs/app/api-reference/functions/redirect) and [`permanentRedirect`](/docs/app/api-reference/functions/permanentRedirect)
## Middleware
Only one middleware file is allowed per project. Use `config.matcher` to target specific paths. Learn more about [middleware](/docs/app/api-reference/file-conventions/middleware).
Use `middleware` to generate a response before the request reaches a route path.
```ts filename="middleware.ts" switcher
import { isAuthenticated } from '@lib/auth'
export const config = {
matcher: '/api/:function*',
}
export function middleware(request: Request) {
if (!isAuthenticated(request)) {
return Response.json(
{ success: false, message: 'authentication failed' },
{ status: 401 }
)
}
}
```
```js filename="middleware.js" switcher
import { isAuthenticated } from '@lib/auth'
export const config = {
matcher: '/api/:function*',
}
export function middleware(request) {
if (!isAuthenticated(request)) {
return Response.json(
{ success: false, message: 'authentication failed' },
{ status: 401 }
)
}
}
```
You can also proxy requests using `middleware`:
```ts filename="middleware.ts" switcher
import { NextResponse } from 'next/server'
export function middleware(request: Request) {
if (request.nextUrl.pathname === '/proxy-this-path') {
const rewriteUrl = new URL('https://nextjs.org')
return NextResponse.rewrite(rewriteUrl)
}
}
```
```js filename="middleware.js" switcher
import { NextResponse } from 'next/server'
export function middleware(request) {
if (request.nextUrl.pathname === '/proxy-this-path') {
const rewriteUrl = new URL('https://nextjs.org')
return NextResponse.rewrite(rewriteUrl)
}
}
```
Another type of response `middleware` can produce are redirects:
```ts filename="middleware.ts" switcher
import { NextResponse } from 'next/server'
export function middleware(request: Request) {
if (request.nextUrl.pathname === '/v1/docs') {
request.nextUrl.pathname = '/v2/docs'
return NextResponse.redirect(request.nextUrl)
}
}
```
```js filename="middleware.js" switcher
import { NextResponse } from 'next/server'
export function middleware(request) {
if (request.nextUrl.pathname === '/v1/docs') {
request.nextUrl.pathname = '/v2/docs'
return NextResponse.redirect(request.nextUrl)
}
}
```
## Security
### Rate limiting
You can implement rate limiting in your Next.js backend. In addition to code-based checks, enable any rate limiting features provided by your host.
```ts filename="/app/resource/route.ts" switcher
import { NextResponse } from 'next/server'
import { checkRateLimit } from '@/lib/rate-limit'
export async function POST(request: Request) {
const { rateLimited } = await checkRateLimit(request)
if (rateLimited) {
return NextResponse.json({ error: 'Rate limit exceeded' }, { status: 429 })
}
return new Response(null, { status: 204 })
}
```
```js filename="/app/resource/route.js" switcher
import { NextResponse } from 'next/server'
import { checkRateLimit } from '@/lib/rate-limit'
export async function POST(request) {
const { rateLimited } = await checkRateLimit(request)
if (rateLimited) {
return NextResponse.json({ error: 'Rate limit exceeded' }, { status: 429 })
}
return new Response(null, { status: 204 })
}
```
### Verify payloads
Never trust incoming request data. Validate content type and size, and sanitize against XSS before use.
Use timeouts to prevent abuse and protect server resources.
Store user-generated static assets in dedicated services. When possible, upload them from the browser and store the returned URI in your database to reduce request size.
### Access to protected resources
Always verify credentials before granting access. Do not rely on middleware alone for authentication and authorization.
Remove sensitive or unnecessary data from responses and backend logs.
Rotate credentials and API keys regularly.
## Preflight Requests
Preflight requests use the `OPTIONS` method to ask the server if a request is allowed based on origin, method, and headers.
If `OPTIONS` is not defined, Next.js adds it automatically and sets the `Allow` header based on the other defined methods.
- [CORS](/docs/app/api-reference/file-conventions/route#cors)
## Library patterns
Community libraries often use the factory pattern for Route Handlers.
```ts filename="/app/api/[...path]/route.ts"
import { createHandler } from 'third-party-library'
const handler = createHandler({
/* library-specific options */
})
export const GET = handler
// or
export { handler as POST }
```
This creates a shared handler for `GET` and `POST` requests. The library customizes behavior based on the `method` and `pathname` in the request.
Libraries can also provide a `middleware` factory.
```ts filename="middleware.ts"
import { createMiddleware } from 'third-party-library'
export default createMiddleware()
```
## More examples
See more examples on using [Router Handlers](/docs/app/api-reference/file-conventions/route#examples) and the [`middleware`](/docs/app/api-reference/file-conventions/middleware#examples) API references.
These examples include, working with [Cookies](/docs/app/api-reference/file-conventions/route#cookies), [Headers](/docs/app/api-reference/file-conventions/route#headers), [Streaming](/docs/app/api-reference/file-conventions/route#streaming), Middleware [negative matching](/docs/app/api-reference/file-conventions/middleware#negative-matching), and other useful code snippets.
## Caveats
### Server Components
Fetch data in Server Components directly from its source, not via Route Handlers.
For Server Components pre-rendered at build time, using Route Handlers will fail the build step. This is because, while building there is no server listening for these requests.
For Server Components rendered on demand, fetching from Route Handlers is slower due to the extra HTTP round trip between the handler and the render process.
> A server side `fetch` request uses absolute URLs. This implies an HTTP round trip, to an external server. During development, your own development server acts as the external server. At build time there is no server, and at runtime, the server is available through your public facing domain.
Server Components cover most data-fetching needs. However, fetching data client side might be necessary for:
- Data that depends on client-only Web APIs:
- Geo-location API
- Storage API
- Audio API
- File API
- Frequently polled data
For these, use community libraries like [`swr`](https://swr.vercel.app/) or [`react-query`](https://tanstack.com/query/latest/docs/framework/react/overview).
### Server Actions
Server Actions let you run server-side code from the client. Their primary purpose is to mutate data from your frontend client.
Server Actions are queued. Using them for data fetching introduces sequential execution.
### `export` mode
`export` mode outputs a static site without a runtime server. Features that require the Next.js runtime are [not supported](/docs/app/guides/static-exports#unsupported-features), because this mode produces a static site, and no runtime server.
In `export mode`, only `GET` Route Handlers are supported, in combination with the [`dynamic`](/docs/app/api-reference/file-conventions/route-segment-config#dynamic) route segment config, set to `'force-static'`.
This can be used to generate static HTML, JSON, TXT, or other files.
```js filename="app/hello-world/route.ts"
export const dynamic = 'force-static'
export function GET() {
return new Response('Hello World', { status: 200 })
}
```
### Deployment environment
Some hosts deploy Route Handlers as lambda functions. This means:
- Route Handlers cannot share data between requests.
- The environment may not support writing to File System.
- Long-running handlers may be terminated due to timeouts.
- WebSockets won’t work because the connection closes on timeout, or after the response is generated.
@@ -303,7 +303,7 @@ By default, the Full Route Cache is persistent. This means that the render outpu
There are two ways you can invalidate the Full Route Cache:
- **[Revalidating Data](/docs/app/deep-dive/caching#revalidating)**: Revalidating the [Data Cache](#data-cache), will in turn invalidate the Router Cache by re-rendering components on the server and caching the new render output.
- **[Revalidating Data](/docs/app/guides/caching#revalidating)**: Revalidating the [Data Cache](#data-cache), will in turn invalidate the Router Cache by re-rendering components on the server and caching the new render output.
- **Redeploying**: Unlike the Data Cache, which persists across deployments, the Full Route Cache is cleared on new deployments.
### Opting out
@@ -370,7 +370,7 @@ When configuring the different caching mechanisms, it's important to understand
### Data Cache and Client-side Router cache
- To immediately invalidate the Data Cache and Router cache, you can use [`revalidatePath`](#revalidatepath) or [`revalidateTag`](#fetch-optionsnexttags-and-revalidatetag) in a [Server Action](/docs/app/getting-started/updating-data).
- Revalidating the Data Cache in a [Route Handler](/docs/app/building-your-application/routing/route-handlers) **will not** immediately invalidate the Router Cache as the Route Handler isn't tied to a specific route. This means Router Cache will continue to serve the previous payload until a hard refresh, or the automatic invalidation period has elapsed.
- Revalidating the Data Cache in a [Route Handler](/docs/app/api-reference/file-conventions/route) **will not** immediately invalidate the Router Cache as the Route Handler isn't tied to a specific route. This means Router Cache will continue to serve the previous payload until a hard refresh, or the automatic invalidation period has elapsed.
## APIs
@@ -474,7 +474,7 @@ revalidateTag('a')
There are two places you can use `revalidateTag`, depending on what you're trying to achieve:
1. [Route Handlers](/docs/app/building-your-application/routing/route-handlers) - to revalidate data in response of a third party event (e.g. webhook). This will not invalidate the Router Cache immediately as the Router Handler isn't tied to a specific route.
1. [Route Handlers](/docs/app/api-reference/file-conventions/route) - to revalidate data in response of a third party event (e.g. webhook). This will not invalidate the Router Cache immediately as the Router Handler isn't tied to a specific route.
2. [Server Actions](/docs/app/getting-started/updating-data) - to revalidate data after a user action (e.g. form submission). This will invalidate the Router Cache for the associated route.
### `revalidatePath`
@@ -487,7 +487,7 @@ revalidatePath('/')
There are two places you can use `revalidatePath`, depending on what you're trying to achieve:
1. [Route Handlers](/docs/app/building-your-application/routing/route-handlers) - to revalidate data in response to a third party event (e.g. webhook).
1. [Route Handlers](/docs/app/api-reference/file-conventions/route) - to revalidate data in response to a third party event (e.g. webhook).
2. [Server Actions](/docs/app/getting-started/updating-data) - to revalidate data after a user interaction (e.g. form submission, clicking a button).
See the [`revalidatePath` API reference](/docs/app/api-reference/functions/revalidatePath) for more information.
@@ -4,7 +4,7 @@ nav_title: Content Security Policy
description: Learn how to set a Content Security Policy (CSP) for your Next.js application.
related:
links:
- app/building-your-application/routing/middleware
- app/api-reference/file-conventions/middleware
- app/api-reference/functions/headers
---
+1 -1
View File
@@ -15,7 +15,7 @@ This page walks through how to enable and use Draft Mode.
## Step 1: Create a Route Handler
Create a [Route Handler](/docs/app/building-your-application/routing/route-handlers). It can have any name, for example, `app/api/draft/route.ts`.
Create a [Route Handler](/docs/app/api-reference/file-conventions/route). It can have any name, for example, `app/api/draft/route.ts`.
```ts filename="app/api/draft/route.ts" switcher
export async function GET(request: Request) {
@@ -61,7 +61,7 @@ export async function getStaticProps() {
> ```
> **Note**: If you are using a `/src` folder, please note that Next.js will load the .env files **only** from the parent folder and **not** from the `/src` folder.
> This loads `process.env.DB_HOST`, `process.env.DB_USER`, and `process.env.DB_PASS` into the Node.js environment automatically allowing you to use them in [Route Handlers](/docs/app/building-your-application/routing/route-handlers).
> This loads `process.env.DB_HOST`, `process.env.DB_USER`, and `process.env.DB_PASS` into the Node.js environment automatically allowing you to use them in [Route Handlers](/docs/app/api-reference/file-conventions/route).
For example:
@@ -377,7 +377,7 @@ export default async function Page() {
}
```
You can then use `revalidateTag` in a [Server Actions](/docs/app/getting-started/updating-data) or [Route Handler](/docs/app/building-your-application/routing/route-handlers):
You can then use `revalidateTag` in a [Server Actions](/docs/app/getting-started/updating-data) or [Route Handler](/docs/app/api-reference/file-conventions/route):
```ts filename="app/actions.ts" switcher
'use server'
@@ -576,7 +576,7 @@ This will make the Next.js server console log ISR cache hits and misses. You can
- ISR is only supported when using the Node.js runtime (default).
- ISR is not supported when creating a [Static Export](/docs/app/guides/static-exports).
- If you have multiple `fetch` requests in a statically rendered route, and each has a different `revalidate` frequency, the lowest time will be used for ISR. However, those revalidate frequencies will still be respected by the [Data Cache](/docs/app/deep-dive/caching#data-cache).
- If you have multiple `fetch` requests in a statically rendered route, and each has a different `revalidate` frequency, the lowest time will be used for ISR. However, those revalidate frequencies will still be respected by the [Data Cache](/docs/app/guides/caching#data-cache).
- If any of the `fetch` requests used on a route have a `revalidate` time of `0`, or an explicit `no-store`, the route will be [dynamically rendered](/docs/app/getting-started/partial-prerendering#dynamic-rendering).
- Middleware won't be executed for on-demand ISR requests, meaning any path rewrites or logic in Middleware will not be applied. Ensure you are revalidating the exact path. For example, `/post/1` instead of a rewritten `/post-1`.
@@ -43,7 +43,7 @@ After you've updated, see the following sections for next steps:
## Upgrading New Features
Next.js 13 introduced the new [App Router](/docs/app/building-your-application/routing) with new features and conventions. The new Router is available in the `app` directory and co-exists with the `pages` directory.
Next.js 13 introduced the new [App Router](/docs/app) with new features and conventions. The new Router is available in the `app` directory and co-exists with the `pages` directory.
Upgrading to Next.js 13 does **not** require using the App Router. You can continue using `pages` with new features that work in both directories, such as the updated [Image component](#image-component), [Link component](#link-component), [Script component](#script-component), and [Font optimization](#font-optimization).
@@ -104,13 +104,13 @@ Moving to the App Router may be the first time using React features that Next.js
We recommend reducing the combined complexity of these updates by breaking down your migration into smaller steps. The `app` directory is intentionally designed to work simultaneously with the `pages` directory to allow for incremental page-by-page migration.
- The `app` directory supports nested routes _and_ layouts. [Learn more](/docs/app/building-your-application/routing).
- The `app` directory supports nested routes _and_ layouts. [Learn more](/docs/app/getting-started/layouts-and-pages).
- Use nested folders to define routes and a special `page.js` file to make a route segment publicly accessible. [Learn more](#step-4-migrating-pages).
- [Special file conventions](/docs/app/api-reference/file-conventions) are used to create UI for each route segment. The most common special files are `page.js` and `layout.js`.
- Use `page.js` to define UI unique to a route.
- Use `layout.js` to define UI that is shared across multiple routes.
- `.js`, `.jsx`, or `.tsx` file extensions can be used for special files.
- You can colocate other files inside the `app` directory such as components, styles, tests, and more. [Learn more](/docs/app/building-your-application/routing).
- You can colocate other files inside the `app` directory such as components, styles, tests, and more. [Learn more](/docs/app).
- Data fetching functions like `getServerSideProps` and `getStaticProps` have been replaced with [a new API](/docs/app/getting-started/fetching-data) inside `app`. `getStaticPaths` has been replaced with [`generateStaticParams`](/docs/app/api-reference/functions/generate-static-params).
- `pages/_app.js` and `pages/_document.js` have been replaced with a single `app/layout.js` root layout. [Learn more](/docs/app/api-reference/file-conventions/layout#root-layout).
- `pages/_error.js` has been replaced with more granular `error.js` special files. [Learn more](/docs/app/getting-started/error-handling).
@@ -325,7 +325,7 @@ export default function Page() {
### Step 4: Migrating Pages
- Pages in the [`app` directory](/docs/app/building-your-application/routing) are [Server Components](/docs/app/getting-started/server-and-client-components) by default. This is different from the `pages` directory where pages are [Client Components](/docs/app/getting-started/server-and-client-components).
- Pages in the [`app` directory](/docs/app) are [Server Components](/docs/app/getting-started/server-and-client-components) by default. This is different from the `pages` directory where pages are [Client Components](/docs/app/getting-started/server-and-client-components).
- [Data fetching](/docs/app/getting-started/fetching-data) has changed in `app`. `getServerSideProps`, `getStaticProps` and `getInitialProps` have been replaced with a simpler API.
- The `app` directory uses nested folders to define routes and a special `page.js` file to make a route segment publicly accessible.
- | `pages` Directory | `app` Directory | Route |
@@ -864,7 +864,7 @@ export default async function PostList() {
#### API Routes
API Routes continue to work in the `pages/api` directory without any changes. However, they have been replaced by [Route Handlers](/docs/app/building-your-application/routing/route-handlers) in the `app` directory.
API Routes continue to work in the `pages/api` directory without any changes. However, they have been replaced by [Route Handlers](/docs/app/api-reference/file-conventions/route) in the `app` directory.
Route Handlers allow you to create custom request handlers for a given route using the Web [Request](https://developer.mozilla.org/docs/Web/API/Request) and [Response](https://developer.mozilla.org/docs/Web/API/Response) APIs.
@@ -569,7 +569,7 @@ You can still provide a [custom webpack configuration](/docs/app/api-reference/c
If everything worked, you now have a functioning Next.js application running as a single-page application. You aren’t yet leveraging Next.js features like server-side rendering or file-based routing, but you can now do so incrementally:
- **Migrate from React Router** to the [Next.js App Router](/docs/app/building-your-application/routing) for:
- **Migrate from React Router** to the [Next.js App Router](/docs/app) for:
- Automatic code splitting
- [Streaming server rendering](/docs/app/api-reference/file-conventions/loading)
- [React Server Components](/docs/app/getting-started/server-and-client-components)
@@ -592,7 +592,7 @@ single-page application. However, you aren't yet taking advantage of most of Nex
you can now start making incremental changes to reap all the benefits. Here's what you might want to
do next:
- Migrate from React Router to the [Next.js App Router](/docs/app/building-your-application/routing) to get:
- Migrate from React Router to the [Next.js App Router](/docs/app) to get:
- Automatic code splitting
- [Streaming Server-Rendering](/docs/app/api-reference/file-conventions/loading)
- [React Server Components](/docs/app/getting-started/server-and-client-components)
+5 -5
View File
@@ -23,11 +23,11 @@ When navigating to the new page, there's no full page reload or browser loading
## Prefetching static vs. dynamic routes
| | **Static page** | **Dynamic page** |
| -------------------------------------------------------------------- | --------------- | -------------------------------------------------------------------------------------------------------------- |
| **Prefetched** | Yes, full route | No, unless [`loading.js`](/docs/app/api-reference/file-conventions/loading) |
| [**Client Cache TTL**](/docs/app/deep-dive/caching#full-route-cache) | 5 min (default) | Off, unless [enabled](/docs/app/api-reference/config/next-config-js/staleTimes) |
| **Server roundtrip on click** | No | Yes, streamed after [shell](/docs/app/getting-started/partial-prerendering#how-does-partial-prerendering-work) |
| | **Static page** | **Dynamic page** |
| ----------------------------------------------------------------- | --------------- | -------------------------------------------------------------------------------------------------------------- |
| **Prefetched** | Yes, full route | No, unless [`loading.js`](/docs/app/api-reference/file-conventions/loading) |
| [**Client Cache TTL**](/docs/app/guides/caching#full-route-cache) | 5 min (default) | Off, unless [enabled](/docs/app/api-reference/config/next-config-js/staleTimes) |
| **Server roundtrip on click** | No | Yes, streamed after [shell](/docs/app/getting-started/partial-prerendering#how-does-partial-prerendering-work) |
> **Good to know:** During the initial navigation, the browser fetches the HTML, JavaScript, and React Server Components (RSC) Payload. For subsequent navigations, the browser will fetch the RSC Payload for Server Components and JS bundle for Client Components.
@@ -18,7 +18,7 @@ These Next.js optimizations are enabled by default and require no configuration:
- **[Code-splitting](/docs/app/getting-started/linking-and-navigating#how-navigation-works):** Server Components enable automatic code-splitting by route segments. You may also consider [lazy loading](/docs/app/guides/lazy-loading) Client Components and third-party libraries, where appropriate.
- **[Prefetching](/docs/app/getting-started/linking-and-navigating#prefetching):** When a link to a new route enters the user's viewport, Next.js prefetches the route in background. This makes navigation to new routes almost instant. You can opt out of prefetching, where appropriate.
- **[Static Rendering](/docs/app/getting-started/partial-prerendering#static-rendering):** Next.js statically renders Server and Client Components on the server at build time and caches the rendered result to improve your application's performance. You can opt into [Dynamic Rendering](/docs/app/getting-started/partial-prerendering#dynamic-rendering) for specific routes, where appropriate. {/* TODO: Update when PPR is stable */}
- **[Caching](/docs/app/deep-dive/caching):** Next.js caches data requests, the rendered result of Server and Client Components, static assets, and more, to reduce the number of network requests to your server, database, and backend services. You may opt out of caching, where appropriate.
- **[Caching](/docs/app/guides/caching):** Next.js caches data requests, the rendered result of Server and Client Components, static assets, and more, to reduce the number of network requests to your server, database, and backend services. You may opt out of caching, where appropriate.
</AppOnly>
@@ -62,10 +62,10 @@ While building your application, we recommend using the following features to en
<AppOnly>
- **[Server Components](/docs/app/getting-started/fetching-data):** Leverage the benefits of fetching data on the server using Server Components.
- **[Route Handlers](/docs/app/building-your-application/routing/route-handlers):** Use Route Handlers to access your backend resources from Client Components. But do not call Route Handlers from Server Components to avoid an additional server request.
- **[Route Handlers](/docs/app/api-reference/file-conventions/route):** Use Route Handlers to access your backend resources from Client Components. But do not call Route Handlers from Server Components to avoid an additional server request.
- **[Streaming](/docs/app/api-reference/file-conventions/loading):** Use Loading UI and React Suspense to progressively send UI from the server to the client, and prevent the whole route from blocking while data is being fetched.
- **[Parallel Data Fetching](/docs/app/getting-started/fetching-data#parallel-data-fetching):** Reduce network waterfalls by fetching data in parallel, where appropriate. Also, consider [preloading data](/docs/app/getting-started/fetching-data#preloading-data) where appropriate.
- **[Data Caching](/docs/app/deep-dive/caching#data-cache):** Verify whether your data requests are being cached or not, and opt into caching, where appropriate. Ensure requests that don't use `fetch` are [cached](/docs/app/api-reference/functions/unstable_cache).
- **[Data Caching](/docs/app/guides/caching#data-cache):** Verify whether your data requests are being cached or not, and opt into caching, where appropriate. Ensure requests that don't use `fetch` are [cached](/docs/app/api-reference/functions/unstable_cache).
- **[Static Images](/docs/app/api-reference/file-conventions/public-folder):** Use the `public` directory to automatically cache your application's static assets, e.g. images.
</AppOnly>
+4 -4
View File
@@ -6,7 +6,7 @@ related:
links:
- app/api-reference/functions/redirect
- app/api-reference/functions/permanentRedirect
- app/building-your-application/routing/middleware
- app/api-reference/file-conventions/middleware
- app/api-reference/config/next-config-js/redirects
---
@@ -38,7 +38,7 @@ There are a few ways you can handle redirects in Next.js. This page will go thro
## `redirect` function
The `redirect` function allows you to redirect the user to another URL. You can call `redirect` in [Server Components](/docs/app/getting-started/server-and-client-components), [Route Handlers](/docs/app/building-your-application/routing/route-handlers), and [Server Actions](/docs/app/getting-started/updating-data).
The `redirect` function allows you to redirect the user to another URL. You can call `redirect` in [Server Components](/docs/app/getting-started/server-and-client-components), [Route Handlers](/docs/app/api-reference/file-conventions/route), and [Server Actions](/docs/app/getting-started/updating-data).
`redirect` is often used after a mutation or event. For example, creating a post:
@@ -90,7 +90,7 @@ See the [`redirect` API reference](/docs/app/api-reference/functions/redirect) f
## `permanentRedirect` function
The `permanentRedirect` function allows you to **permanently** redirect the user to another URL. You can call `permanentRedirect` in [Server Components](/docs/app/getting-started/server-and-client-components), [Route Handlers](/docs/app/building-your-application/routing/route-handlers), and [Server Actions](/docs/app/getting-started/updating-data).
The `permanentRedirect` function allows you to **permanently** redirect the user to another URL. You can call `permanentRedirect` in [Server Components](/docs/app/getting-started/server-and-client-components), [Route Handlers](/docs/app/api-reference/file-conventions/route), and [Server Actions](/docs/app/getting-started/updating-data).
`permanentRedirect` is often used after a mutation or event that changes an entity's canonical URL, such as updating a user's profile URL after they change their username:
@@ -430,7 +430,7 @@ Reading a large dataset for every incoming request can be slow and expensive. Th
Considering the previous example, you can import a generated bloom filter file into Middleware, then, check if the incoming request pathname exists in the bloom filter.
If it does, forward the request to a <AppOnly>[Route Handler](/docs/app/building-your-application/routing/route-handlers)</AppOnly> <PagesOnly>[API Routes](/docs/pages/building-your-application/routing/api-routes)</PagesOnly> which will check the actual file and redirect the user to the appropriate URL. This avoids importing a large redirects file into Middleware, which can slow down every incoming request.
If it does, forward the request to a <AppOnly>[Route Handler](/docs/app/api-reference/file-conventions/route)</AppOnly> <PagesOnly>[API Routes](/docs/pages/building-your-application/routing/api-routes)</PagesOnly> which will check the actual file and redirect the user to the appropriate URL. This avoids importing a large redirects file into Middleware, which can slow down every incoming request.
```ts filename="middleware.ts" switcher
import { NextResponse, NextRequest } from 'next/server'
+1 -1
View File
@@ -279,7 +279,7 @@ Features that require a Node.js server, or dynamic logic that cannot be computed
- [Dynamic Routes](/docs/app/api-reference/file-conventions/dynamic-routes) with `dynamicParams: true`
- [Dynamic Routes](/docs/app/api-reference/file-conventions/dynamic-routes) without `generateStaticParams()`
- [Route Handlers](/docs/app/building-your-application/routing/route-handlers) that rely on Request
- [Route Handlers](/docs/app/api-reference/file-conventions/route) that rely on Request
- [Cookies](/docs/app/api-reference/functions/cookies)
- [Rewrites](/docs/app/api-reference/config/next-config-js/rewrites)
- [Redirects](/docs/app/api-reference/config/next-config-js/redirects)
@@ -169,7 +169,7 @@ export default function Icon() {
> - By default, generated icons are [**statically optimized**](/docs/app/getting-started/partial-prerendering#static-rendering) (generated at build time and cached) unless they use [Dynamic APIs](/docs/app/getting-started/partial-prerendering#dynamic-rendering#dynamic-apis) or uncached data.
> - You can generate multiple icons in the same file using [`generateImageMetadata`](/docs/app/api-reference/functions/generate-image-metadata).
> - You cannot generate a `favicon` icon. Use [`icon`](#icon) or a [favicon.ico](#favicon) file instead.
> - App icons are special Route Handlers that is cached by default unless it uses a [Dynamic API](/docs/app/deep-dive/caching#dynamic-apis) or [dynamic config](/docs/app/deep-dive/caching#segment-config-options) option.
> - App icons are special Route Handlers that are cached by default unless they use a [Dynamic API](/docs/app/guides/caching#dynamic-apis) or [dynamic config](/docs/app/guides/caching#segment-config-options) option.
### Props
@@ -250,7 +250,7 @@ export default function Icon() {}
#### Route Segment Config
`icon` and `apple-icon` are specialized [Route Handlers](/docs/app/building-your-application/routing/route-handlers) that can use the same [route segment configuration](/docs/app/api-reference/file-conventions/route-segment-config) options as Pages and Layouts.
`icon` and `apple-icon` are specialized [Route Handlers](/docs/app/api-reference/file-conventions/route) that can use the same [route segment configuration](/docs/app/api-reference/file-conventions/route-segment-config) options as Pages and Layouts.
## Version History
@@ -21,7 +21,7 @@ Add or generate a `manifest.(json|webmanifest)` file that matches the [Web Manif
Add a `manifest.js` or `manifest.ts` file that returns a [`Manifest` object](#manifest-object).
> Good to know: `manifest.js` is special Route Handlers that is cached by default unless it uses a [Dynamic API](/docs/app/deep-dive/caching#dynamic-apis) or [dynamic config](/docs/app/deep-dive/caching#segment-config-options) option.
> Good to know: `manifest.js` is special Route Handlers that is cached by default unless it uses a [Dynamic API](/docs/app/guides/caching#dynamic-apis) or [dynamic config](/docs/app/guides/caching#segment-config-options) option.
```ts filename="app/manifest.ts" switcher
import type { MetadataRoute } from 'next'
@@ -90,7 +90,7 @@ Generate a route segment's shared image by creating an `opengraph-image` or `twi
>
> - By default, generated images are [**statically optimized**](/docs/app/getting-started/partial-prerendering#static-rendering) (generated at build time and cached) unless they use [Dynamic APIs](/docs/app/getting-started/partial-prerendering#dynamic-rendering#dynamic-apis) or uncached data.
> - You can generate multiple Images in the same file using [`generateImageMetadata`](/docs/app/api-reference/functions/generate-image-metadata).
> - `opengraph-image.js` and `twitter-image.js` are special Route Handlers that is cached by default unless it uses a [Dynamic API](/docs/app/deep-dive/caching#dynamic-apis) or [dynamic config](/docs/app/deep-dive/caching#segment-config-options) option.
> - `opengraph-image.js` and `twitter-image.js` are special Route Handlers that is cached by default unless it uses a [Dynamic API](/docs/app/guides/caching#dynamic-apis) or [dynamic config](/docs/app/guides/caching#segment-config-options) option.
The easiest way to generate an image is to use the [ImageResponse](/docs/app/api-reference/functions/image-response) API from `next/og`.
@@ -313,7 +313,7 @@ export default function Image() {}
#### Route Segment Config
`opengraph-image` and `twitter-image` are specialized [Route Handlers](/docs/app/building-your-application/routing/route-handlers) that can use the same [route segment configuration](/docs/app/api-reference/file-conventions/route-segment-config) options as Pages and Layouts.
`opengraph-image` and `twitter-image` are specialized [Route Handlers](/docs/app/api-reference/file-conventions/route) that can use the same [route segment configuration](/docs/app/api-reference/file-conventions/route-segment-config) options as Pages and Layouts.
### Examples
@@ -19,7 +19,7 @@ Sitemap: https://acme.com/sitemap.xml
Add a `robots.js` or `robots.ts` file that returns a [`Robots` object](#robots-object).
> **Good to know**: `robots.js` is a special Route Handlers that is cached by default unless it uses a [Dynamic API](/docs/app/deep-dive/caching#dynamic-apis) or [dynamic config](/docs/app/deep-dive/caching#segment-config-options) option.
> **Good to know**: `robots.js` is a special Route Handlers that is cached by default unless it uses a [Dynamic API](/docs/app/guides/caching#dynamic-apis) or [dynamic config](/docs/app/guides/caching#segment-config-options) option.
```ts filename="app/robots.ts" switcher
import type { MetadataRoute } from 'next'
@@ -41,7 +41,7 @@ For smaller applications, you can create a `sitemap.xml` file and place it in th
You can use the `sitemap.(js|ts)` file convention to programmatically **generate** a sitemap by exporting a default function that returns an array of URLs. If using TypeScript, a [`Sitemap`](#returns) type is available.
> **Good to know**: `sitemap.js` is a special Route Handler that is cached by default unless it uses a [Dynamic API](/docs/app/deep-dive/caching#dynamic-apis) or [dynamic config](/docs/app/deep-dive/caching#segment-config-options) option.
> **Good to know**: `sitemap.js` is a special Route Handler that is cached by default unless it uses a [Dynamic API](/docs/app/guides/caching#dynamic-apis) or [dynamic config](/docs/app/guides/caching#segment-config-options) option.
```ts filename="app/sitemap.ts" switcher
import type { MetadataRoute } from 'next'
@@ -33,7 +33,7 @@ export default async function Page({ params }) {
}
```
Dynamic Segments are passed as the `params` prop to [`layout`](/docs/app/api-reference/file-conventions/layout), [`page`](/docs/app/api-reference/file-conventions/page), [`route`](/docs/app/building-your-application/routing/route-handlers), and [`generateMetadata`](/docs/app/api-reference/functions/generate-metadata#generatemetadata-function) functions.
Dynamic Segments are passed as the `params` prop to [`layout`](/docs/app/api-reference/file-conventions/layout), [`page`](/docs/app/api-reference/file-conventions/page), [`route`](/docs/app/api-reference/file-conventions/route), and [`generateMetadata`](/docs/app/api-reference/functions/generate-metadata#generatemetadata-function) functions.
| Route | Example URL | `params` |
| ------------------------- | ----------- | --------------- |
@@ -110,4 +110,4 @@ export async function generateStaticParams() {
}
```
When using `fetch` inside the `generateStaticParams` function, the requests are [automatically deduplicated](/docs/app/deep-dive/caching#request-memoization). This avoids multiple network calls for the same data Layouts, Pages, and other `generateStaticParams` functions, speeding up build time.
When using `fetch` inside the `generateStaticParams` function, the requests are [automatically deduplicated](/docs/app/guides/caching#request-memoization). This avoids multiple network calls for the same data Layouts, Pages, and other `generateStaticParams` functions, speeding up build time.
@@ -149,7 +149,7 @@ The `NextResponse` API allows you to:
To produce a response from Middleware, you can:
1. `rewrite` to a route ([Page](/docs/app/api-reference/file-conventions/page) or [Route Handler](/docs/app/building-your-application/routing/route-handlers)) that produces a response
1. `rewrite` to a route ([Page](/docs/app/api-reference/file-conventions/page) or [Route Handler](/docs/app/api-reference/file-conventions/route)) that produces a response
2. return a `NextResponse` directly. See [Producing a Response](#producing-a-response)
> **Good to know**: For redirects, you can also use `Response.redirect` instead of `NextResponse.redirect`.
@@ -5,7 +5,7 @@ description: Learn about how to configure options for Next.js route segments.
> The options outlined on this page are disabled if the [`dynamicIO`](/docs/app/api-reference/config/next-config-js/dynamicIO) flag is on, and will eventually be deprecated in the future.
The Route Segment options allows you to configure the behavior of a [Page](/docs/app/api-reference/file-conventions/layout), [Layout](/docs/app/api-reference/file-conventions/layout), or [Route Handler](/docs/app/building-your-application/routing/route-handlers) by directly exporting the following variables:
The Route Segment options allows you to configure the behavior of a [Page](/docs/app/api-reference/file-conventions/layout), [Layout](/docs/app/api-reference/file-conventions/layout), or [Route Handler](/docs/app/api-reference/file-conventions/route) by directly exporting the following variables:
| Option | Type | Default |
| --------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- | -------------------------- |
@@ -5,7 +5,7 @@ description: API Reference for the after function.
`after` allows you to schedule work to be executed after a response (or prerender) is finished. This is useful for tasks and other side effects that should not block the response, such as logging and analytics.
It can be used in [Server Components](/docs/app/getting-started/server-and-client-components) (including [`generateMetadata`](https://nextjs.org/docs/app/api-reference/functions/generate-metadata)), [Server Actions](/docs/app/getting-started/updating-data), [Route Handlers](/docs/app/building-your-application/routing/route-handlers), and [Middleware](/docs/app/api-reference/file-conventions/middleware).
It can be used in [Server Components](/docs/app/getting-started/server-and-client-components) (including [`generateMetadata`](https://nextjs.org/docs/app/api-reference/functions/generate-metadata)), [Server Actions](/docs/app/getting-started/updating-data), [Route Handlers](/docs/app/api-reference/file-conventions/route), and [Middleware](/docs/app/api-reference/file-conventions/middleware).
The function accepts a callback that will be executed after the response (or prerender) is finished:
@@ -64,7 +64,7 @@ export async function getData() {
}
```
You can then purge the cache on-demand using [`revalidateTag`](/docs/app/api-reference/functions/revalidateTag) API in another function, for example, a [route handler](/docs/app/building-your-application/routing/route-handlers) or [Server Action](/docs/app/getting-started/updating-data):
You can then purge the cache on-demand using [`revalidateTag`](/docs/app/api-reference/functions/revalidateTag) API in another function, for example, a [route handler](/docs/app/api-reference/file-conventions/route) or [Server Action](/docs/app/getting-started/updating-data):
```tsx filename="app/action.ts" switcher
'use server'
@@ -3,7 +3,7 @@ title: cookies
description: API Reference for the cookies function.
---
`cookies` is an **async** function that allows you to read the HTTP incoming request cookies in [Server Components](/docs/app/getting-started/server-and-client-components), and read/write outgoing request cookies in [Server Actions](/docs/app/getting-started/updating-data) or [Route Handlers](/docs/app/building-your-application/routing/route-handlers).
`cookies` is an **async** function that allows you to read the HTTP incoming request cookies in [Server Components](/docs/app/getting-started/server-and-client-components), and read/write outgoing request cookies in [Server Actions](/docs/app/getting-started/updating-data) or [Route Handlers](/docs/app/api-reference/file-conventions/route).
```tsx filename="app/page.tsx" switcher
import { cookies } from 'next/headers'
@@ -70,9 +70,9 @@ To learn more about these options, see the [MDN docs](https://developer.mozilla.
- In version 14 and earlier, `cookies` was a synchronous function. To help with backwards compatibility, you can still access it synchronously in Next.js 15, but this behavior will be deprecated in the future.
- `cookies` is a [Dynamic API](/docs/app/getting-started/partial-prerendering#dynamic-rendering) whose returned values cannot be known ahead of time. Using it in a layout or page will opt a route into [dynamic rendering](/docs/app/getting-started/partial-prerendering#dynamic-rendering).
- The `.delete` method can only be called:
- In a [Server Action](/docs/app/getting-started/updating-data) or [Route Handler](/docs/app/building-your-application/routing/route-handlers).
- In a [Server Action](/docs/app/getting-started/updating-data) or [Route Handler](/docs/app/api-reference/file-conventions/route).
- If it belongs to the same domain from which `.set` is called. For wildcard domains, the specific subdomain must be an exact match. Additionally, the code must be executed on the same protocol (HTTP or HTTPS) as the cookie you want to delete.
- HTTP does not allow setting cookies after streaming starts, so you must use `.set` in a [Server Action](/docs/app/getting-started/updating-data) or [Route Handler](/docs/app/building-your-application/routing/route-handlers).
- HTTP does not allow setting cookies after streaming starts, so you must use `.set` in a [Server Action](/docs/app/getting-started/updating-data) or [Route Handler](/docs/app/api-reference/file-conventions/route).
## Understanding Cookie Behavior in Server Components
@@ -143,7 +143,7 @@ export default async function Page() {
### Setting a cookie
You can use the `(await cookies()).set(name, value, options)` method in a [Server Action](/docs/app/getting-started/updating-data) or [Route Handler](/docs/app/building-your-application/routing/route-handlers) to set a cookie. The [`options` object](#options) is optional.
You can use the `(await cookies()).set(name, value, options)` method in a [Server Action](/docs/app/getting-started/updating-data) or [Route Handler](/docs/app/api-reference/file-conventions/route) to set a cookie. The [`options` object](#options) is optional.
```tsx filename="app/actions.ts" switcher
'use server'
@@ -47,7 +47,7 @@ The following methods and properties are available:
### Enabling Draft Mode
To enable Draft Mode, create a new [Route Handler](/docs/app/building-your-application/routing/route-handlers) and call the `enable()` method:
To enable Draft Mode, create a new [Route Handler](/docs/app/api-reference/file-conventions/route) and call the `enable()` method:
```tsx filename="app/draft/route.ts" switcher
import { draftMode } from 'next/headers'
@@ -73,7 +73,7 @@ export async function GET(request) {
By default, the Draft Mode session ends when the browser is closed.
To disable Draft Mode manually, call the `disable()` method in your [Route Handler](/docs/app/building-your-application/routing/route-handlers):
To disable Draft Mode manually, call the `disable()` method in your [Route Handler](/docs/app/api-reference/file-conventions/route):
```tsx filename="app/draft/route.ts" switcher
import { draftMode } from 'next/headers'
@@ -5,7 +5,7 @@ description: API reference for the extended fetch function.
Next.js extends the [Web `fetch()` API](https://developer.mozilla.org/docs/Web/API/Fetch_API) to allow each request on the server to set its own persistent caching and revalidation semantics.
In the browser, the `cache` option indicates how a fetch request will interact with the _browser's_ HTTP cache. With this extension, `cache` indicates how a _server-side_ fetch request will interact with the framework's persistent [Data Cache](/docs/app/deep-dive/caching#data-cache).
In the browser, the `cache` option indicates how a fetch request will interact with the _browser's_ HTTP cache. With this extension, `cache` indicates how a _server-side_ fetch request will interact with the framework's persistent [Data Cache](/docs/app/guides/caching#data-cache).
You can call `fetch` with `async` and `await` directly within Server Components.
@@ -43,7 +43,7 @@ Since Next.js extends the [Web `fetch()` API](https://developer.mozilla.org/docs
### `options.cache`
Configure how the request should interact with Next.js [Data Cache](/docs/app/deep-dive/caching#data-cache).
Configure how the request should interact with Next.js [Data Cache](/docs/app/guides/caching#data-cache).
```ts
fetch(`https://...`, { cache: 'force-cache' | 'no-store' })
@@ -31,7 +31,7 @@ module.exports = {
}
```
`forbidden` can be invoked in [Server Components](/docs/app/getting-started/server-and-client-components), [Server Actions](/docs/app/getting-started/updating-data), and [Route Handlers](/docs/app/building-your-application/routing/route-handlers).
`forbidden` can be invoked in [Server Components](/docs/app/getting-started/server-and-client-components), [Server Actions](/docs/app/getting-started/updating-data), and [Route Handlers](/docs/app/api-reference/file-conventions/route).
```tsx filename="app/auth/page.tsx" switcher
import { verifySession } from '@/app/lib/dal'
@@ -101,8 +101,10 @@ export default function Page({ params, searchParams }) {}
> - Next.js will automatically resolve the metadata, and create the relevant `<head>` tags for the page.
> - The `metadata` object and `generateMetadata` function exports are **only supported in Server Components**.
> - You cannot export both the `metadata` object and `generateMetadata` function from the same route segment.
> - `fetch` requests inside `generateMetadata` are automatically [memoized](/docs/app/deep-dive/caching#request-memoization) for the same data across `generateMetadata`, `generateStaticParams`, Layouts, Pages, and Server Components.
> - React [`cache` can be used](/docs/app/deep-dive/caching#react-cache-function) if `fetch` is unavailable. -[ File-based metadata](/docs/app/api-reference/file-conventions/metadata) has the higher priority and will override the `metadata` object and `generateMetadata` function.
> - `fetch` requests inside `generateMetadata` are automatically [memoized](/docs/app/guides/caching#request-memoization) for the same data across `generateMetadata`, `generateStaticParams`, Layouts, Pages, and Server Components.
> - React [`cache` can be used](/docs/app/guides/caching#react-cache-function) if `fetch` is unavailable.
> - [File-based metadata](/docs/app/api-reference/file-conventions/metadata) has the higher priority and will override the `metadata` object and `generateMetadata` function.
## Reference
@@ -137,7 +139,7 @@ export default function Page({ params, searchParams }) {}
> **Good to know**:
>
> - If metadata doesn't depend on runtime information, it should be defined using the static [`metadata` object](#the-metadata-object) rather than `generateMetadata`.
> - `fetch` requests are automatically [memoized](/docs/app/deep-dive/caching#request-memoization) for the same data across `generateMetadata`, `generateStaticParams`, Layouts, Pages, and Server Components. React [`cache` can be used](/docs/app/deep-dive/caching#react-cache-function) if `fetch` is unavailable.
> - `fetch` requests are automatically [memoized](/docs/app/guides/caching#request-memoization) for the same data across `generateMetadata`, `generateStaticParams`, Layouts, Pages, and Server Components. React [`cache` can be used](/docs/app/guides/caching#react-cache-function) if `fetch` is unavailable.
> - `searchParams` are only available in `page.js` segments.
> - The [`redirect()`](/docs/app/api-reference/functions/redirect) and [`notFound()`](/docs/app/api-reference/functions/not-found) Next.js methods can also be used inside `generateMetadata`.
@@ -436,7 +436,7 @@ export default function Page({ params }) {
}
```
> **Good to know**: `fetch` requests are automatically [memoized](/docs/app/deep-dive/caching#request-memoization) for the same data across all `generate`-prefixed functions, Layouts, Pages, and Server Components. React [`cache` can be used](/docs/app/deep-dive/caching#react-cache-function) if `fetch` is unavailable.
> **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
@@ -6,7 +6,7 @@ related:
- app/api-reference/functions/redirect
---
The `permanentRedirect` function allows you to redirect the user to another URL. `permanentRedirect` can be used in Server Components, Client Components, [Route Handlers](/docs/app/building-your-application/routing/route-handlers), and [Server Actions](/docs/app/getting-started/updating-data).
The `permanentRedirect` function allows you to redirect the user to another URL. `permanentRedirect` can be used in Server Components, Client Components, [Route Handlers](/docs/app/api-reference/file-conventions/route), and [Server Actions](/docs/app/getting-started/updating-data).
When used in a streaming context, this will insert a meta tag to emit the redirect on the client side. When used in a server action, it will serve a 303 HTTP redirect response to the caller. Otherwise, it will serve a 308 (Permanent) HTTP redirect response to the caller.
@@ -6,7 +6,7 @@ related:
- app/api-reference/functions/permanentRedirect
---
The `redirect` function allows you to redirect the user to another URL. `redirect` can be used in [Server Components](/docs/app/getting-started/server-and-client-components), [Route Handlers](/docs/app/building-your-application/routing/route-handlers), and [Server Actions](/docs/app/getting-started/updating-data).
The `redirect` function allows you to redirect the user to another URL. `redirect` can be used in [Server Components](/docs/app/getting-started/server-and-client-components), [Route Handlers](/docs/app/api-reference/file-conventions/route), and [Server Actions](/docs/app/getting-started/updating-data).
When used in a [streaming context](/docs/app/getting-started/linking-and-navigating#streaming), this will insert a meta tag to emit the redirect on the client side. When used in a server action, it will serve a 303 HTTP redirect response to the caller. Otherwise, it will serve a 307 HTTP redirect response to the caller.
@@ -3,13 +3,13 @@ title: revalidatePath
description: API Reference for the revalidatePath function.
---
`revalidatePath` allows you to purge [cached data](/docs/app/deep-dive/caching) on-demand for a specific path.
`revalidatePath` allows you to purge [cached data](/docs/app/guides/caching) on-demand for a specific path.
> **Good to know**:
>
> - `revalidatePath` only invalidates the cache when the included path is next visited. This means calling `revalidatePath` with a dynamic route segment will not immediately trigger many revalidations at once. The invalidation only happens when the path is next visited.
> - Currently, `revalidatePath` invalidates all the routes in the [client-side Router Cache](/docs/app/deep-dive/caching#client-side-router-cache) when used in a server action. This behavior is temporary and will be updated in the future to apply only to the specific path.
> - Using `revalidatePath` invalidates **only the specific path** in the [server-side Route Cache](/docs/app/deep-dive/caching#full-route-cache).
> - Currently, `revalidatePath` invalidates all the routes in the [client-side Router Cache](/docs/app/guides/caching#client-side-router-cache) when used in a server action. This behavior is temporary and will be updated in the future to apply only to the specific path.
> - Using `revalidatePath` invalidates **only the specific path** in the [server-side Route Cache](/docs/app/guides/caching#full-route-cache).
## Parameters
@@ -3,7 +3,7 @@ title: revalidateTag
description: API Reference for the revalidateTag function.
---
`revalidateTag` allows you to purge [cached data](/docs/app/deep-dive/caching) on-demand for a specific cache tag.
`revalidateTag` allows you to purge [cached data](/docs/app/guides/caching) on-demand for a specific cache tag.
> **Good to know**:
>
@@ -31,7 +31,7 @@ module.exports = {
}
```
`unauthorized` can be invoked in [Server Components](/docs/app/getting-started/server-and-client-components), [Server Actions](/docs/app/getting-started/updating-data), and [Route Handlers](/docs/app/building-your-application/routing/route-handlers).
`unauthorized` can be invoked in [Server Components](/docs/app/getting-started/server-and-client-components), [Server Actions](/docs/app/getting-started/updating-data), and [Route Handlers](/docs/app/api-reference/file-conventions/route).
```tsx filename="app/dashboard/page.tsx" switcher
import { verifySession } from '@/app/lib/dal'
@@ -25,7 +25,7 @@ export default async function Component({ userID }) {
> **Good to know**:
>
> - Accessing dynamic data sources such as `headers` or `cookies` inside a cache scope is not supported. If you need this data inside a cached function use `headers` outside of the cached function and pass the required dynamic data in as an argument.
> - This API uses Next.js' built-in [Data Cache](/docs/app/deep-dive/caching#data-cache) to persist the result across requests and deployments.
> - This API uses Next.js' built-in [Data Cache](/docs/app/guides/caching#data-cache) to persist the result across requests and deployments.
## Parameters
@@ -6,6 +6,6 @@ version: legacy
> **Good to know**: This option is **no longer** needed as of Next.js 13.4. The App Router is now stable.
The App Router ([`app` directory](/docs/app/building-your-application/routing)) enables support for [layouts](/docs/app/api-reference/file-conventions/layout), [Server Components](/docs/app/getting-started/server-and-client-components), [streaming](/docs/app/api-reference/file-conventions/loading), and [colocated data fetching](/docs/app/getting-started/fetching-data).
The App Router ([`app` directory](/docs/app)) enables support for [layouts](/docs/app/api-reference/file-conventions/layout), [Server Components](/docs/app/getting-started/server-and-client-components), [streaming](/docs/app/api-reference/file-conventions/loading), and [colocated data fetching](/docs/app/getting-started/fetching-data).
Using the `app` directory will automatically enable [React Strict Mode](https://react.dev/reference/react/StrictMode). Learn how to [incrementally adopt `app`](/docs/app/guides/migrating/app-router-migration#migrating-from-pages-to-app).

Some files were not shown because too many files have changed in this diff Show More