Skip to content

Commit 6ba8ec8

Browse files
authored
docs: getting started updates 01 (vercel#85750)
1 parent 90d8759 commit 6ba8ec8

File tree

6 files changed

+71
-31
lines changed

6 files changed

+71
-31
lines changed

docs/01-app/01-getting-started/06-cache-components.mdx

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -232,37 +232,52 @@ Like Server Actions, arguments to cached functions must be serializable. This me
232232
You can accept unserializable values as arguments as long as you don't introspect them. However, you can return them. This allows patterns like cached components that accept Server or Client Components as children:
233233

234234
```tsx filename="app/cached-wrapper.tsx" switcher
235-
import { ReactNode } from 'react'
235+
import type { ReactNode } from 'react'
236+
import { setTimeout } from 'node:timers/promises'
237+
238+
async function getSiteTitle() {
239+
// Simulate a slow database or API call
240+
await setTimeout(1000) // from 'node:timers/promises'
241+
return 'My Website'
242+
}
236243

237244
export async function CachedWrapper({ children }: { children: ReactNode }) {
238245
'use cache'
246+
const title = await getSiteTitle()
247+
239248
// Don't introspect children, just pass it through
240249
return (
241250
<div className="wrapper">
242-
<header>Cached Header</header>
251+
<h1>{title}</h1>
243252
{children}
244253
</div>
245254
)
246255
}
247256
```
248257

249258
```jsx filename="app/cached-wrapper.js" switcher
259+
import { setTimeout } from 'node:timers/promises'
260+
261+
async function getSiteTitle() {
262+
// Simulate a slow database or API call
263+
await setTimeout(1000) // from 'node:timers/promises'
264+
return 'My Website'
265+
}
266+
250267
export async function CachedWrapper({ children }) {
251268
'use cache'
269+
const title = await getSiteTitle()
270+
252271
// Don't introspect children, just pass it through
253272
return (
254273
<div className="wrapper">
255-
<header>Cached Header</header>
274+
<h1>{title}</h1>
256275
{children}
257276
</div>
258277
)
259278
}
260279
```
261280

262-
#### Avoid passing dynamic inputs
263-
264-
You must not pass dynamic or runtime data into `use cache` functions unless you avoid introspecting them. Passing values from `cookies()`, `headers()`, or other runtime APIs as arguments will cause errors, as the cache key cannot be determined at pre-render time.
265-
266281
### Tagging and revalidating
267282

268283
Tag cached data with [`cacheTag`](/docs/app/api-reference/functions/cacheTag) and revalidate it after mutations using [`updateTag`](/docs/app/api-reference/functions/updateTag) in Server Actions for immediate updates, or [`revalidateTag`](/docs/app/api-reference/functions/revalidateTag) delay in updates are acceptable.
@@ -521,7 +536,7 @@ export default function Page() {
521536
522537
### Passing dynamic props
523538
524-
Components only opt into dynamic rendering when the value is accessed. For example, if you are reading `searchParams` from a `<Page />` component, you can forward this value to another component as a prop:
539+
Components that access runtime values like `cookies` or `searchParams` cannot be prerendered. To prerender more of a page's content, you can pass these props down and access their values lower in the tree. For example, if you are reading `searchParams` from a `<Page />` component, you can forward this value to another component as a prop:
525540
526541
```tsx filename="app/page.tsx" switcher
527542
import { Table, TableSkeleton } from './table'

docs/01-app/01-getting-started/07-fetching-data.mdx

Lines changed: 14 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,11 @@ This page will walk you through how you can fetch data in [Server and Client Com
1818

1919
### Server Components
2020

21-
You can fetch data in Server Components using:
21+
You can fetch data in Server Components using any asynchronous I/O, such as:
2222

2323
1. The [`fetch` API](#with-the-fetch-api)
2424
2. An [ORM or database](#with-an-orm-or-database)
25+
3. Reading from the filesystem using Node.js APIs like `fs`
2526

2627
#### With the `fetch` API
2728

@@ -285,7 +286,7 @@ To improve the initial load time and user experience, you can use streaming to b
285286
height="785"
286287
/>
287288

288-
There are two ways you can implement streaming in your application:
289+
There are two ways you can leverage streaming in your application:
289290

290291
1. Wrapping a page with a [`loading.js` file](#with-loadingjs)
291292
2. Wrapping a component with [`<Suspense>`](#with-suspense)
@@ -356,7 +357,7 @@ export default function BlogPage() {
356357
<p>Read the latest posts below.</p>
357358
</header>
358359
<main>
359-
{/* Any content wrapped in a <Suspense> boundary will be streamed */}
360+
{/* If there's any dynamic content inside this boundary, it will be streamed in */}
360361
<Suspense fallback={<BlogListSkeleton />}>
361362
<BlogList />
362363
</Suspense>
@@ -380,7 +381,7 @@ export default function BlogPage() {
380381
<p>Read the latest posts below.</p>
381382
</header>
382383
<main>
383-
{/* Any content wrapped in a <Suspense> boundary will be streamed */}
384+
{/* If there's any dynamic content inside this boundary, it will be streamed in */}
384385
<Suspense fallback={<BlogListSkeleton />}>
385386
<BlogList />
386387
</Suspense>
@@ -400,19 +401,9 @@ In development, you can preview and inspect the loading state of your components
400401

401402
### Sequential data fetching
402403

403-
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.
404+
Sequential data fetching happens when one request depends on data from another.
404405

405-
<Image
406-
alt="Sequential and Parallel Data Fetching"
407-
srcLight="/docs/light/sequential-parallel-data-fetching.png"
408-
srcDark="/docs/dark/sequential-parallel-data-fetching.png"
409-
width="1600"
410-
height="525"
411-
/>
412-
413-
There may be cases where you want this pattern because one fetch depends on the result of the other.
414-
415-
For example, the `<Playlists>` component will only start fetching data once the `<Artist>` component has finished fetching data because `<Playlists>` depends on the `artistID` prop:
406+
For example, `<Playlists>` can only fetch data after `<Artist>` completes because it needs the `artistID`:
416407

417408
```tsx filename="app/artist/[username]/page.tsx" switcher
418409
export default async function Page({
@@ -482,7 +473,9 @@ async function Playlists({ artistID }) {
482473
}
483474
```
484475

485-
To improve the user experience, you should use [React `<Suspense>`](/docs/app/getting-started/linking-and-navigating#streaming) to show a `fallback` while data is being fetch. This will enable [streaming](#streaming) and prevent the whole route from being blocked by the sequential data requests.
476+
In this example, `<Suspense>` allows the playlists to stream in after the artist data loads. However, the page still waits for the artist data before displaying anything. To prevent this, you can wrap the entire page component in a `<Suspense>` boundary (for example, using a [`loading.js` file](#with-loadingjs)) to show a loading state immediately.
477+
478+
Ensure your data source can resolve the first request quickly, as it blocks everything else. If you can't optimize the request further, consider [caching](#deduplicate-requests-and-cache-data) the result if the data changes infrequently.
486479

487480
### Parallel data fetching
488481

@@ -597,11 +590,12 @@ export default async function Page({
597590
return isAvailable ? <Item id={id} /> : null
598591
}
599592

600-
export const preload = (id: string) => {
593+
const preload = (id: string) => {
601594
// void evaluates the given expression and returns undefined
602595
// https://developer.mozilla.org/docs/Web/JavaScript/Reference/Operators/void
603596
void getItem(id)
604597
}
598+
605599
export async function Item({ id }: { id: string }) {
606600
const result = await getItem(id)
607601
// ...
@@ -621,11 +615,12 @@ export default async function Page({ params }) {
621615
return isAvailable ? <Item id={id} /> : null
622616
}
623617

624-
export const preload = (id) => {
618+
const preload = (id) => {
625619
// void evaluates the given expression and returns undefined
626620
// https://developer.mozilla.org/docs/Web/JavaScript/Reference/Operators/void
627621
void getItem(id)
628622
}
623+
629624
export async function Item({ id }) {
630625
const result = await getItem(id)
631626
// ...

docs/01-app/01-getting-started/08-updating-data.mdx

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,38 @@ export function Button() {
328328
}
329329
```
330330

331+
### Refreshing
332+
333+
After a mutation, you may want to refresh the current page to show the latest data. You can do this by calling [`refresh`](/docs/app/api-reference/functions/refresh) from `next/cache` in a Server Action:
334+
335+
```ts filename="app/lib/actions.ts" switcher
336+
'use server'
337+
338+
import { refresh } from 'next/cache'
339+
340+
export async function updatePost(formData: FormData) {
341+
// Update data
342+
// ...
343+
344+
refresh()
345+
}
346+
```
347+
348+
```js filename="app/lib/actions.js" switcher
349+
'use server'
350+
351+
import { refresh } from 'next/cache'
352+
353+
export async function updatePost(formData) {
354+
// Update data
355+
// ...
356+
357+
refresh()
358+
}
359+
```
360+
361+
This refreshes the client router, ensuring the UI reflects the latest state. The `refresh()` function does not revalidate tagged data. To revalidate tagged data, use [`updateTag`](/docs/app/api-reference/functions/updateTag) or [`revalidateTag`](/docs/app/api-reference/functions/revalidateTag) instead.
362+
331363
### Revalidating
332364

333365
After performing an update, you can revalidate the Next.js cache and show the updated data by calling [`revalidatePath`](/docs/app/api-reference/functions/revalidatePath) or [`revalidateTag`](/docs/app/api-reference/functions/revalidateTag) within the Server Function:

docs/01-app/03-api-reference/04-functions/refresh.mdx

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ refresh(): void;
2525
'use server'
2626

2727
import { refresh } from 'next/cache'
28-
import { redirect } from 'next/navigation'
2928

3029
export async function createPost(formData: FormData) {
3130
const title = formData.get('title')
@@ -44,7 +43,6 @@ export async function createPost(formData: FormData) {
4443
'use server'
4544

4645
import { refresh } from 'next/cache'
47-
import { redirect } from 'next/navigation'
4846

4947
export async function createPost(formData) {
5048
const title = formData.get('title')

docs/01-app/03-api-reference/05-config/01-next-config-js/mdxRs.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
title: mdxRs
33
description: Use the new Rust compiler to compile MDX files in the App Router.
4-
version: experimental.
4+
version: experimental
55
---
66

77
For experimental use with `@next/mdx`. Compiles MDX files using the new Rust compiler.

docs/01-app/03-api-reference/06-cli/next.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ The following options are available for the `next telemetry` command:
149149

150150
Learn more about [Telemetry](/telemetry).
151151

152-
### `next typegen` Options
152+
### `next typegen` options
153153

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

0 commit comments

Comments
 (0)