Skip to content

Commit 92b4d67

Browse files
leerobbalazsorban44delbaoliveira
authored
docs: Next.js 14 (#57342)
- Fetch logging configuration is no longer experimental - Add `unstable_noStore` reference - Add `unstable_cache` reference - Add codemod docs for `next/og` import changes - Update docs around stable Server Actions - Add example of revalidating the entire data cache - Update static export docs for `next export` command removal - Update minimum required Node.js version - Add `viewport` and `generateViewport` reference Co-authored-by: Balázs Orbán <[email protected]> Co-authored-by: Delba de Oliveira <[email protected]>
1 parent fd0a96f commit 92b4d67

File tree

27 files changed

+459
-203
lines changed

27 files changed

+459
-203
lines changed

docs/01-getting-started/01-installation.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ related:
1010

1111
System Requirements:
1212

13-
- [Node.js 16.14](https://nodejs.org/) or later.
13+
- [Node.js 18.17](https://nodejs.org/) or later.
1414
- macOS, Windows (including WSL), and Linux are supported.
1515

1616
## Automatic Installation

docs/02-app/01-building-your-application/02-data-fetching/01-fetching-caching-and-revalidating.mdx

Lines changed: 15 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ There are four ways you can fetch data:
1717

1818
Next.js extends the native [`fetch` Web API](https://developer.mozilla.org/docs/Web/API/Fetch_API) to allow you to configure the [caching](#caching-data) and [revalidating](#revalidating-data) behavior for each fetch request on the server. React extends `fetch` to automatically [memoize](/docs/app/building-your-application/data-fetching/patterns#fetching-data-where-its-needed) fetch requests while rendering a React component tree.
1919

20-
You can use `fetch` with [`async`/`await` in Server Components](https://github.com/acdlite/rfcs/blob/first-class-promises/text/0000-first-class-support-for-promises.md), in [Route Handlers](/docs/app/building-your-application/routing/route-handlers), and in [Server Actions](/docs/app/building-your-application/data-fetching/forms-and-mutations).
20+
You can use `fetch` with `async`/`await` in Server Components, in [Route Handlers](/docs/app/building-your-application/routing/route-handlers), and in [Server Actions](/docs/app/building-your-application/data-fetching/forms-and-mutations).
2121

2222
For example:
2323

@@ -117,7 +117,7 @@ Learn more about [time-based revalidation](/docs/app/building-your-application/c
117117

118118
#### On-demand Revalidation
119119

120-
Data can be revalidated on-demand by path ([`revalidatePath`](/docs/app/api-reference/functions/revalidatePath)) or by cache tag ([`revalidateTag`](/docs/app/api-reference/functions/revalidateTag)) inside a Route Handler or a Server Action.
120+
Data can be revalidated on-demand by path ([`revalidatePath`](/docs/app/api-reference/functions/revalidatePath)) or by cache tag ([`revalidateTag`](/docs/app/api-reference/functions/revalidateTag)) inside a [Server Action](/docs/app/building-your-application/data-fetching/forms-and-mutations) or [Route Handler](/docs/app/building-your-application/routing/route-handlers).
121121

122122
Next.js has a cache tagging system for invalidating `fetch` requests across routes.
123123

@@ -142,89 +142,25 @@ export default async function Page() {
142142
}
143143
```
144144

145-
If using a Route Handler, you should create a secret token only known by your Next.js app. This secret will be used to prevent unauthorized revalidation attempts. For example, you can access the route (either manually or with a webhook) with the following URL structure:
145+
You can then revalidate this `fetch` call tagged with `collection` by calling `revalidateTag` in a Server Action:
146146

147-
```bash filename="URL"
148-
https://<your-site.com>/api/revalidate?tag=collection&secret=<token>
149-
```
150-
151-
```ts filename="app/api/revalidate/route.ts" switcher
152-
import { NextRequest } from 'next/server'
153-
import { revalidateTag } from 'next/cache'
154-
155-
// e.g a webhook to `your-website.com/api/revalidate?tag=collection&secret=<token>`
156-
export async function POST(request: NextRequest) {
157-
const secret = request.nextUrl.searchParams.get('secret')
158-
const tag = request.nextUrl.searchParams.get('tag')
159-
160-
if (secret !== process.env.MY_SECRET_TOKEN) {
161-
return Response.json({ message: 'Invalid secret' }, { status: 401 })
162-
}
163-
164-
if (!tag) {
165-
return Response.json({ message: 'Missing tag param' }, { status: 400 })
166-
}
167-
168-
revalidateTag(tag)
147+
```ts filename="app/actions.ts" switcher
148+
'use server'
169149

170-
return Response.json({ revalidated: true, now: Date.now() })
171-
}
172-
```
173-
174-
```js filename="app/api/revalidate/route.js" switcher
175150
import { revalidateTag } from 'next/cache'
176151

177-
// e.g a webhook to `your-website.com/api/revalidate?tag=collection&secret=<token>`
178-
export async function POST(request) {
179-
const secret = request.nextUrl.searchParams.get('secret')
180-
const tag = request.nextUrl.searchParams.get('tag')
181-
182-
if (secret !== process.env.MY_SECRET_TOKEN) {
183-
return Response.json({ message: 'Invalid secret' }, { status: 401 })
184-
}
185-
186-
if (!tag) {
187-
return Response.json({ message: 'Missing tag param' }, { status: 400 })
188-
}
189-
190-
revalidateTag(tag)
191-
192-
return Response.json({ revalidated: true, now: Date.now() })
152+
export default async function action() {
153+
revalidateTag('collection')
193154
}
194155
```
195156

196-
Alternatively, you can use [`revalidatePath`](/docs/app/api-reference/functions/revalidatePath) to revalidate all data associated with a path.
157+
```js filename="app/actions.js" switcher
158+
'use server'
197159

198-
```ts filename="app/api/revalidate/route.ts" switcher
199-
import { NextRequest } from 'next/server'
200-
import { revalidatePath } from 'next/cache'
201-
202-
export async function POST(request: NextRequest) {
203-
const path = request.nextUrl.searchParams.get('path')
204-
205-
if (!path) {
206-
return Response.json({ message: 'Missing path param' }, { status: 400 })
207-
}
208-
209-
revalidatePath(path)
210-
211-
return Response.json({ revalidated: true, now: Date.now() })
212-
}
213-
```
214-
215-
```js filename="app/api/revalidate/route.js" switcher
216-
import { revalidatePath } from 'next/cache'
217-
218-
export async function POST(request) {
219-
const path = request.nextUrl.searchParams.get('path')
220-
221-
if (!path) {
222-
return Response.json({ message: 'Missing path param' }, { status: 400 })
223-
}
224-
225-
revalidatePath(path)
160+
import { revalidateTag } from 'next/cache'
226161

227-
return Response.json({ revalidated: true, now: Date.now() })
162+
export default async function action() {
163+
revalidateTag('collection')
228164
}
229165
```
230166

@@ -260,24 +196,15 @@ View all the available `cache` options in the [`fetch` API reference](/docs/app/
260196

261197
If you have multiple `fetch` requests in a route segment (e.g. a Layout or Page), you can configure the caching behavior of all data requests in the segment using the [Segment Config Options](/docs/app/api-reference/file-conventions/route-segment-config).
262198

263-
For example, using `const dynamic = 'force-dynamic'` will cause all data to be fetched at request time, and the segment to be rendered dynamically.
264-
265-
```js filename="layout.js | page.js"
266-
// Add
267-
export const dynamic = 'force-dynamic'
268-
```
269-
270-
There's an extensive list of Segment Config options, giving you fine-grained control of static and dynamic behavior of a route segment. See the [API reference](/docs/app/api-reference/file-conventions/route-segment-config) for more.
199+
However, we recommend configuring the caching behavior of each `fetch` request individually. This gives you more granular control over the caching behavior.
271200

272201
## Fetching data on the Server with third-party libraries
273202

274203
In cases where you're using a third-party library that doesn't support or expose `fetch` (for example, a database, CMS, or ORM client), you can configure the caching and revalidating behavior of those requests using the [Route Segment Config Option](/docs/app/api-reference/file-conventions/route-segment-config) and React's `cache` function.
275204

276205
Whether the data is cached or not will depend on whether the route segment is [statically or dynamically rendered](/docs/app/building-your-application/rendering/server-components#server-rendering-strategies). If the segment is static (default), the output of the request will be cached and revalidated as part of the route segment. If the segment is dynamic, the output of the request will _not_ be cached and will be re-fetched on every request when the segment is rendered.
277206

278-
> **Good to know:**
279-
>
280-
> Next.js is working on an API, `unstable_cache`, for configuring the caching and revalidating behavior of individual third-party requests.
207+
You can also use the experimental [`unstable_cache` API](/docs/app/api-reference/functions/unstable_cache).
281208

282209
### Example
283210

@@ -370,4 +297,4 @@ You can also fetch data on the client using a third-party library such as [SWR](
370297

371298
> **Future APIs**:
372299
>
373-
> `use` is a React function that **accepts and handles a promise** returned by a function. Wrapping `fetch` in `use` is currently **not** recommended in Client Components and may trigger multiple re-renders. Learn more about `use` in the [React RFC](https://github.com/acdlite/rfcs/blob/first-class-promises/text/0000-first-class-support-for-promises.md#usepromise).
300+
> `use` is a React function that **accepts and handles a promise** returned by a function. Wrapping `fetch` in `use` is currently **not** recommended in Client Components and may trigger multiple re-renders. Learn more about `use` in the [React docs](https://react.dev/reference/react/use).

docs/02-app/01-building-your-application/02-data-fetching/03-forms-and-mutations.mdx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -360,7 +360,7 @@ export default async function submit(formData) {
360360

361361
<AppOnly>
362362

363-
Use the `useFormStatus` hook to show a loading state when a form is submitting on the server. The `useFormStatus` hook can only be used as a child of a `form` element using a Server Action.
363+
Use the [`useFormStatus`](https://react.dev/reference/react-dom/hooks/useFormStatus) hook to show a loading state when a form is submitting on the server. The `useFormStatus` hook can only be used as a child of a `form` element using a Server Action.
364364

365365
For example, the following submit button:
366366

@@ -731,7 +731,7 @@ Use `useOptimistic` to optimistically update the UI before the Server Action fin
731731
```tsx filename="app/page.tsx" switcher
732732
'use client'
733733

734-
import { experimental_useOptimistic as useOptimistic } from 'react'
734+
import { useOptimistic } from 'react'
735735
import { send } from './actions'
736736

737737
type Message = {
@@ -770,7 +770,7 @@ export function Thread({ messages }: { messages: Message[] }) {
770770
```jsx filename="app/page.jsx" switcher
771771
'use client'
772772

773-
import { experimental_useOptimistic as useOptimistic } from 'react'
773+
import { useOptimistic } from 'react'
774774
import { send } from './actions'
775775

776776
export function Thread({ messages }) {

docs/02-app/01-building-your-application/03-rendering/02-client-components.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,4 +103,4 @@ This means the Client Component JavaScript bundle is downloaded and parsed. Once
103103

104104
Sometimes, after you've declared the `"use client"` boundary, you may want to go back to the server environment. For example, you may want to reduce the client bundle size, fetch data on the server, or use an API that is only available on the server.
105105

106-
You can keep code on the server even though it's theoretically nested inside Client Components by interleaving Client and Server Components and Server Actions. See the [Composition Patterns](/docs/app/building-your-application/rendering/composition-patterns) page for more information.
106+
You can keep code on the server even though it's theoretically nested inside Client Components by interleaving Client and Server Components and [Server Actions](/docs/app/building-your-application/data-fetching/forms-and-mutations). See the [Composition Patterns](/docs/app/building-your-application/rendering/composition-patterns) page for more information.

docs/02-app/01-building-your-application/04-caching/index.mdx

Lines changed: 2 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -417,7 +417,7 @@ The following table provides an overview of how different Next.js APIs affect ca
417417
| [`headers`, `useSearchParams`, `searchParams`](#dynamic-functions) | | Opt out | | |
418418
| [`generateStaticParams`](#generatestaticparams) | | Cache | | |
419419
| [`React.cache`](#react-cache-function) | | | | Cache |
420-
| [`unstable_cache`](#unstable_cache) (Coming Soon) | | | | |
420+
| [`unstable_cache`](/docs/app/api-reference/functions/unstable_cache) | | | | |
421421

422422
### `<Link>`
423423

@@ -480,7 +480,7 @@ See the [`fetch` API reference](/docs/app/api-reference/functions/fetch) for mor
480480

481481
Next.js has a cache tagging system for fine-grained data caching and revalidation.
482482

483-
1. When using `fetch` or `unstable_cache`, you have the option to tag cache entries with one or more tags.
483+
1. When using `fetch` or [`unstable_cache`](/docs/app/api-reference/functions/unstable_cache), you have the option to tag cache entries with one or more tags.
484484
2. Then, you can call `revalidateTag` to purge the cache entries associated with that tag.
485485

486486
For example, you can set a tag when fetching data:
@@ -577,27 +577,3 @@ export const getItem = cache(async (id) => {
577577
return item
578578
})
579579
```
580-
581-
### `unstable_cache`
582-
583-
`unstable_cache` is an experimental API for adding values to the Data Cache when the `fetch` API is not suitable. For example, when using database clients, CMS clients, or GraphQL.
584-
585-
```jsx
586-
import { unstable_cache } from 'next/cache'
587-
588-
export default async function Page() {
589-
const cachedData = await unstable_cache(
590-
async () => {
591-
const data = await db.query('...')
592-
return data
593-
},
594-
['cache-key'],
595-
{
596-
tags: ['a', 'b', 'c'],
597-
revalidate: 10,
598-
}
599-
)()
600-
}
601-
```
602-
603-
> **Warning**: This API is being developed, and we do not recommend using it in production. It's listed here to show the future direction of the Data Cache.

docs/02-app/01-building-your-application/06-optimizing/04-metadata.mdx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ related:
66
links:
77
- app/api-reference/functions/generate-metadata
88
- app/api-reference/file-conventions/metadata
9+
- app/api-reference/functions/generate-viewport
910
---
1011

1112
Next.js has a Metadata API that can be used to define your application metadata (e.g. `meta` and `link` tags inside your HTML `head` element) for improved SEO and web shareability.

docs/02-app/01-building-your-application/06-optimizing/index.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ Metadata helps search engines understand your content better (which can result i
2424

2525
The Metadata API in Next.js allows you to modify the `<head>` element of a page. You can configure metadata in two ways:
2626

27-
- **Config-based Metadata**: Export a static metadata object or a dynamic generateMetadata function in a `layout.js` or `page.js` file.
27+
- **Config-based Metadata**: Export a [static `metadata` object](/docs/app/api-reference/functions/generate-metadata#metadata-object) or a dynamic [`generateMetadata` function](/docs/app/api-reference/functions/generate-metadata#generatemetadata-function) in a `layout.js` or `page.js` file.
2828
- **File-based Metadata**: Add static or dynamically generated special files to route segments.
2929

3030
Additionally, you can create dynamic Open Graph Images using JSX and CSS with [imageResponse](/docs/app/api-reference/functions/image-response) constructor.

docs/02-app/01-building-your-application/08-deploying/01-static-exports.mdx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,7 @@ export const dynamic = 'error'
323323

324324
With a static export, Next.js can be deployed and hosted on any web server that can serve HTML/CSS/JS static assets.
325325

326-
When running `next build`, Next.js generates the static export into the `out` folder. Using `next export` is no longer needed. For example, let's say you have the following routes:
326+
When running `next build`, Next.js generates the static export into the `out` folder. For example, let's say you have the following routes:
327327

328328
- `/`
329329
- `/blog/[id]`
@@ -365,5 +365,6 @@ server {
365365

366366
| Version | Changes |
367367
| --------- | -------------------------------------------------------------------------------------------------------------------- |
368+
| `v14.0.0` | `next export` has been removed in favor of `"output": "export"` |
368369
| `v13.4.0` | App Router (Stable) adds enhanced static export support, including using React Server Components and Route Handlers. |
369370
| `v13.3.0` | `next export` is deprecated and replaced with `"output": "export"` |

docs/02-app/01-building-your-application/09-upgrading/01-codemods.mdx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,15 +34,15 @@ Replacing `<transform>` and `<path>` with appropriate values.
3434
npx @next/codemod@latest next-og-import.
3535
```
3636

37-
This codemo migrates the import path of `ImageResponse` from `'next/server'` to `'next/og'`
37+
This codemod moves transforms imports from `next/server` to `next/og` for usage of [Dynamic OG Image Generation](/docs/app/building-your-application/optimizing/metadata#dynamic-image-generation).
3838

3939
For example:
4040

4141
```js
4242
import { ImageResponse } from 'next/server'
4343
```
4444

45-
Transform into:
45+
Transforms into:
4646

4747
```js
4848
import { ImageResponse } from 'next/og'

docs/02-app/01-building-your-application/09-upgrading/02-app-router-migration.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ This guide will help you:
1414

1515
### Node.js Version
1616

17-
The minimum Node.js version is now **v16.14**. See the [Node.js documentation](https://nodejs.org/docs/latest-v16.x/api/) for more information.
17+
The minimum Node.js version is now **v18.17**. See the [Node.js documentation](https://nodejs.org/docs/latest-v18.x/api/) for more information.
1818

1919
### Next.js Version
2020

0 commit comments

Comments
 (0)