Skip to content

Commit f390079

Browse files
authored
Merge branch '10-13-_do_not_merge_eslint' into 10-14-test_improve_linting
2 parents 23dd9c1 + 3650648 commit f390079

File tree

202 files changed

+2570
-1187
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

202 files changed

+2570
-1187
lines changed

docs/02-app/01-building-your-application/01-routing/13-route-handlers.mdx

Lines changed: 15 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ export async function GET() {
8484
8585
### Special Route Handlers
8686

87-
Special Route Handlers like [`sitemap.ts`](/docs/app/api-reference/file-conventions/metadata/sitemap), [`opengraph-image.tsx`](/docs/app/api-reference/file-conventions/metadata/opengraph-image), and [`icon.tsx`](/docs/app/api-reference/file-conventions/metadata/app-icons), and other [metadata files](/docs/app/api-reference/file-conventions/metadata) remain static by default unless they use dynamic functions or dynamic config options.
87+
Special Route Handlers like [`sitemap.ts`](/docs/app/api-reference/file-conventions/metadata/sitemap), [`opengraph-image.tsx`](/docs/app/api-reference/file-conventions/metadata/opengraph-image), and [`icon.tsx`](/docs/app/api-reference/file-conventions/metadata/app-icons), and other [metadata files](/docs/app/api-reference/file-conventions/metadata) remain static by default unless they use Dynamic APIs or dynamic config options.
8888

8989
### Route Resolution
9090

@@ -141,11 +141,7 @@ export async function GET() {
141141
}
142142
```
143143

144-
### Dynamic Functions
145-
146-
Route Handlers can be used with dynamic functions from Next.js, like [`cookies`](/docs/app/api-reference/functions/cookies) and [`headers`](/docs/app/api-reference/functions/headers).
147-
148-
#### Cookies
144+
### Cookies
149145

150146
You can read or set cookies with [`cookies`](/docs/app/api-reference/functions/cookies) from `next/headers`. This server function can be called directly in a Route Handler, or nested inside of another function.
151147

@@ -155,7 +151,7 @@ Alternatively, you can return a new `Response` using the [`Set-Cookie`](https://
155151
import { cookies } from 'next/headers'
156152

157153
export async function GET(request: Request) {
158-
const cookieStore = cookies()
154+
const cookieStore = await cookies()
159155
const token = cookieStore.get('token')
160156

161157
return new Response('Hello, Next.js!', {
@@ -169,7 +165,7 @@ export async function GET(request: Request) {
169165
import { cookies } from 'next/headers'
170166

171167
export async function GET(request) {
172-
const cookieStore = cookies()
168+
const cookieStore = await cookies()
173169
const token = cookieStore.get('token')
174170

175171
return new Response('Hello, Next.js!', {
@@ -195,7 +191,7 @@ export async function GET(request) {
195191
}
196192
```
197193

198-
#### Headers
194+
### Headers
199195

200196
You can read headers with [`headers`](/docs/app/api-reference/functions/headers) from `next/headers`. This server function can be called directly in a Route Handler, or nested inside of another function.
201197

@@ -205,7 +201,7 @@ This `headers` instance is read-only. To set headers, you need to return a new `
205201
import { headers } from 'next/headers'
206202

207203
export async function GET(request: Request) {
208-
const headersList = headers()
204+
const headersList = await headers()
209205
const referer = headersList.get('referer')
210206

211207
return new Response('Hello, Next.js!', {
@@ -219,7 +215,7 @@ export async function GET(request: Request) {
219215
import { headers } from 'next/headers'
220216

221217
export async function GET(request) {
222-
const headersList = headers()
218+
const headersList = await headers()
223219
const referer = headersList.get('referer')
224220

225221
return new Response('Hello, Next.js!', {
@@ -272,23 +268,23 @@ Route Handlers can use [Dynamic Segments](/docs/app/building-your-application/ro
272268
```ts filename="app/items/[slug]/route.ts" switcher
273269
export async function GET(
274270
request: Request,
275-
{ params }: { params: { slug: string } }
271+
{ params }: { params: Promise<{ slug: string }> }
276272
) {
277-
const slug = params.slug // 'a', 'b', or 'c'
273+
const slug = (await params).slug // 'a', 'b', or 'c'
278274
}
279275
```
280276

281277
```js filename="app/items/[slug]/route.js" switcher
282278
export async function GET(request, { params }) {
283-
const slug = params.slug // 'a', 'b', or 'c'
279+
const slug = (await params).slug // 'a', 'b', or 'c'
284280
}
285281
```
286282

287-
| Route | Example URL | `params` |
288-
| --------------------------- | ----------- | --------------- |
289-
| `app/items/[slug]/route.js` | `/items/a` | `{ slug: 'a' }` |
290-
| `app/items/[slug]/route.js` | `/items/b` | `{ slug: 'b' }` |
291-
| `app/items/[slug]/route.js` | `/items/c` | `{ slug: 'c' }` |
283+
| Route | Example URL | `params` |
284+
| --------------------------- | ----------- | ------------------------ |
285+
| `app/items/[slug]/route.js` | `/items/a` | `Promise<{ slug: 'a' }>` |
286+
| `app/items/[slug]/route.js` | `/items/b` | `Promise<{ slug: 'b' }>` |
287+
| `app/items/[slug]/route.js` | `/items/c` | `Promise<{ slug: 'c' }>` |
292288

293289
### URL Query Parameters
294290

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ export default async function Page() {
8787
}
8888
```
8989

90-
If you are not using any [dynamic functions](/docs/app/building-your-application/rendering/server-components#dynamic-rendering) anywhere else in this route, it will be prerendered during `next build` to a static page. The data can then be updated using [Incremental Static Regeneration](/docs/app/building-your-application/data-fetching/incremental-static-regeneration).
90+
If you are not using any [Dynamic APIs](/docs/app/building-your-application/rendering/server-components#dynamic-rendering) anywhere else in this route, it will be prerendered during `next build` to a static page. The data can then be updated using [Incremental Static Regeneration](/docs/app/building-your-application/data-fetching/incremental-static-regeneration).
9191

9292
If you do _not_ want to cache the response from `fetch`, you can do the following:
9393

@@ -129,15 +129,15 @@ export default async function Page() {
129129
}
130130
```
131131

132-
If you are not using any [dynamic functions](/docs/app/building-your-application/rendering/server-components#dynamic-rendering) anywhere else in this route, it will be prerendered during `next build` to a static page. The data can then be updated using [Incremental Static Regeneration](/docs/app/building-your-application/data-fetching/incremental-static-regeneration).
132+
If you are not using any [Dynamic APIs](/docs/app/building-your-application/rendering/server-components#dynamic-rendering) anywhere else in this route, it will be prerendered during `next build` to a static page. The data can then be updated using [Incremental Static Regeneration](/docs/app/building-your-application/data-fetching/incremental-static-regeneration).
133133

134134
To prevent the page from prerendering, you can add the following to your file:
135135

136136
```js
137137
export const dynamic = 'force-dynamic'
138138
```
139139

140-
However, you will commonly use functions like `cookies()`, `headers()`, or reading the incoming `searchParams` from the page props, which will automatically make the page render dynamically. In this case, you do _not_ need to explicitly use `force-dynamic`.
140+
However, you will commonly use functions like `cookies`, `headers`, or reading the incoming `searchParams` from the page props, which will automatically make the page render dynamically. In this case, you do _not_ need to explicitly use `force-dynamic`.
141141

142142
### Fetching data on the client
143143

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

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -838,14 +838,16 @@ You can `get`, `set`, and `delete` cookies inside a Server Action using the [`co
838838
import { cookies } from 'next/headers'
839839

840840
export async function exampleAction() {
841+
const cookieStore = await cookies()
842+
841843
// Get cookie
842-
const value = cookies().get('name')?.value
844+
cookieStore.get('name')?.value
843845

844846
// Set cookie
845-
cookies().set('name', 'Delba')
847+
cookieStore.set('name', 'Delba')
846848

847849
// Delete cookie
848-
cookies().delete('name')
850+
cookieStore.delete('name')
849851
}
850852
```
851853
@@ -856,23 +858,49 @@ import { cookies } from 'next/headers'
856858

857859
export async function exampleAction() {
858860
// Get cookie
859-
const value = cookies().get('name')?.value
861+
const cookieStore = await cookies()
862+
863+
// Get cookie
864+
cookieStore.get('name')?.value
860865

861866
// Set cookie
862-
cookies().set('name', 'Delba')
867+
cookieStore.set('name', 'Delba')
863868

864869
// Delete cookie
865-
cookies().delete('name')
870+
cookieStore.delete('name')
866871
}
867872
```
868873
869874
See [additional examples](/docs/app/api-reference/functions/cookies#deleting-cookies) for deleting cookies from Server Actions.
870875
871876
## Security
872877
878+
By default, when a Server Action is created and exported, it creates a public HTTP endpoint
879+
and should be treated with the same security assumptions and authorization checks. This means, even if a Server Action or utility function is not imported elsewhere in your code, it’s still a publicly accessible.
880+
881+
To improve security, Next.js has the following built-in features:
882+
883+
- **Dead code elimination:** Unused Server Actions won’t have their IDs exposed to the client-side JavaScript bundle, reducing bundle size and improving performance.
884+
- **Secure action IDs:** Next.js creates unguessable, non-deterministic IDs to allow the client to reference and call the Server Action. These IDs are periodically recalculated for enhanced security.
885+
886+
```jsx
887+
// app/actions.js
888+
'use server'
889+
890+
// This action **is** used in our application, so Next.js
891+
// will create a secure ID to allow the client to reference
892+
// and call the Server Action.
893+
export async function updateUserAction(formData) {}
894+
895+
// This action **is not** used in our application, so Next.js
896+
// will automatically remove this code during `next build`
897+
// and will not create a public endpoint.
898+
export async function deleteUserAction(formData) {}
899+
```
900+
873901
### Authentication and authorization
874902
875-
You should treat Server Actions as you would public-facing API endpoints, and ensure that the user is authorized to perform the action. For example:
903+
You should ensure that the user is authorized to perform the action. For example:
876904
877905
```tsx filename="app/actions.ts"
878906
'use server'

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

Lines changed: 16 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -62,16 +62,12 @@ There are three subsets of server rendering: Static, Dynamic, and Streaming.
6262

6363
### Static Rendering (Default)
6464

65-
{/* Static Rendering Diagram */}
66-
6765
With Static Rendering, routes are rendered at **build time**, or in the background after [data revalidation](/docs/app/building-your-application/data-fetching/incremental-static-regeneration). The result is cached and can be pushed to a [Content Delivery Network (CDN)](https://developer.mozilla.org/docs/Glossary/CDN). This optimization allows you to share the result of the rendering work between users and server requests.
6866

6967
Static rendering is useful when a route has data that is not personalized to the user and can be known at build time, such as a static blog post or a product page.
7068

7169
### Dynamic Rendering
7270

73-
{/* Dynamic Rendering Diagram */}
74-
7571
With Dynamic Rendering, routes are rendered for each user at **request time**.
7672

7773
Dynamic rendering is useful when a route has data that is personalized to the user or has information that can only be known at request time, such as cookies or the URL's search params.
@@ -86,30 +82,30 @@ Dynamic rendering is useful when a route has data that is personalized to the us
8682
8783
#### Switching to Dynamic Rendering
8884

89-
During rendering, if a [dynamic function](#dynamic-functions) or uncached data request is discovered, Next.js will switch to dynamically rendering the whole route. This table summarizes how dynamic functions and data caching affect whether a route is statically or dynamically rendered:
85+
During rendering, if a [Dynamic API](#dynamic-apis) or uncached data request is discovered, Next.js will switch to dynamically rendering the whole route. This table summarizes how Dynamic APIs and data caching affect whether a route is statically or dynamically rendered:
9086

91-
| Dynamic Functions | Data | Route |
92-
| ----------------- | ---------- | -------------------- |
93-
| No | Cached | Statically Rendered |
94-
| Yes | Cached | Dynamically Rendered |
95-
| No | Not Cached | Dynamically Rendered |
96-
| Yes | Not Cached | Dynamically Rendered |
87+
| Dynamic APIs | Data | Route |
88+
| ------------ | ---------- | -------------------- |
89+
| No | Cached | Statically Rendered |
90+
| Yes | Cached | Dynamically Rendered |
91+
| No | Not Cached | Dynamically Rendered |
92+
| Yes | Not Cached | Dynamically Rendered |
9793

9894
In the table above, for a route to be fully static, all data must be cached. However, you can have a dynamically rendered route that uses both cached and uncached data fetches.
9995

10096
As a developer, you do not need to choose between static and dynamic rendering as Next.js will automatically choose the best rendering strategy for each route based on the features and APIs used. Instead, you choose when to [cache](/docs/app/building-your-application/data-fetching/fetching) or [revalidate specific data](/docs/app/building-your-application/data-fetching/incremental-static-regeneration), and you may choose to [stream](#streaming) parts of your UI.
10197

102-
#### Dynamic Functions
103-
104-
Dynamic functions rely on information that can only be known at request time such as a user's cookies, current requests headers, or the URL's search params. In Next.js, these dynamic APIs are:
98+
### Dynamic APIs
10599

106-
- [`cookies()`](/docs/app/api-reference/functions/cookies)
107-
- [`headers()`](/docs/app/api-reference/functions/headers)
108-
- [`unstable_noStore()`](/docs/app/api-reference/functions/unstable_noStore)
109-
- [`unstable_after()`](/docs/app/api-reference/functions/unstable_after):
110-
- [`searchParams` prop](/docs/app/api-reference/file-conventions/page#searchparams-optional)
100+
Dynamic APIs rely on information that can only be known at request time (and not ahead of time during prerendering). Using any of these APIs signals the developer's intention and will opt the whole route into dynamic rendering at the request time. These APIs include:
111101

112-
Using any of these functions will opt the whole route into dynamic rendering at request time.
102+
- [`cookies`](https://www.notion.so/docs/app/api-reference/functions/cookies)
103+
- [`headers`](https://www.notion.so/docs/app/api-reference/functions/headers)
104+
- [`unstable_noStore`](https://www.notion.so/docs/app/api-reference/functions/unstable_noStore)
105+
- [`unstable_after`](https://www.notion.so/docs/app/api-reference/functions/unstable_after)
106+
- [`connection`](https://www.notion.so/docs/app/api-reference/functions/connection)
107+
- [`draftMode`](https://www.notion.so/docs/app/api-reference/functions/draft-mode)
108+
- [`searchParams` prop](https://www.notion.so/docs/app/api-reference/file-conventions/page#searchparams-optional)
113109

114110
### Streaming
115111

docs/02-app/01-building-your-application/03-rendering/04-partial-prerendering.mdx

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -127,24 +127,24 @@ module.exports = nextConfig
127127

128128
## Dynamic Components
129129

130-
When creating the prerender for your route during `next build`, Next.js requires that dynamic functions are wrapped with React Suspense. The `fallback` is then included in the prerender.
130+
When creating the prerender for your route during `next build`, Next.js requires that Dynamic APIs are wrapped with React Suspense. The `fallback` is then included in the prerender.
131131

132-
For example, using functions like `cookies()` or `headers()`:
132+
For example, using functions like `cookies` or `headers`:
133133

134134
```jsx filename="app/user.js" switcher
135135
import { cookies } from 'next/headers'
136136

137-
export function User() {
138-
const session = cookies().get('session')?.value
137+
export async function User() {
138+
const session = (await cookies()).get('session')?.value
139139
return '...'
140140
}
141141
```
142142
143143
```tsx filename="app/user.tsx" switcher
144144
import { cookies } from 'next/headers'
145145

146-
export function User() {
147-
const session = cookies().get('session')?.value
146+
export async function User() {
147+
const session = (await cookies()).get('session')?.value
148148
return '...'
149149
}
150150
```
@@ -224,17 +224,21 @@ export default function Page({ searchParams }) {
224224
Inside of the table component, accessing the value from `searchParams` will make the component run dynamically:
225225
226226
```tsx filename="app/table.tsx" switcher
227-
export function Table({ searchParams }: { searchParams: { sort: string } }) {
228-
const sort = searchParams.sort === 'true'
227+
export async function Table({
228+
searchParams,
229+
}: {
230+
searchParams: Promise<{ sort: string }>
231+
}) {
232+
const sort = (await searchParams).sort === 'true'
229233
return '...'
230234
}
231235
```
232236
233237
```jsx filename="app/table.js" switcher
234-
export function Table({ searchParams }: {
235-
searchParams: { sort: string }
238+
export async function Table({ searchParams }: {
239+
searchParams: Promise<{ sort: string }>
236240
}) {
237-
const sort = searchParams.sort === 'true';
241+
const sort = (await searchParams).sort === 'true';
238242
return '...'
239243
}
240244
```

0 commit comments

Comments
 (0)