Skip to content

Commit

Permalink
Merge branch 'vercel:canary' into patch-2
Browse files Browse the repository at this point in the history
  • Loading branch information
cwtuan committed May 8, 2024
2 parents 6f33355 + 0edf4f9 commit 5605fd0
Show file tree
Hide file tree
Showing 678 changed files with 396,369 additions and 454,443 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -358,10 +358,10 @@ export default async function createsUser(formData) {
}
```

Once the fields have been validated on the server, you can return a serializable object in your action and use the React [`useFormState`](https://react.dev/reference/react-dom/hooks/useFormState) hook to show a message to the user.
Once the fields have been validated on the server, you can return a serializable object in your action and use the React [`useActionState`](https://react.dev/reference/react/useActionState) hook to show a message to the user.

- By passing the action to `useFormState`, the action's function signature changes to receive a new `prevState` or `initialState` parameter as its first argument.
- `useFormState` is a React hook and therefore must be used in a Client Component.
- By passing the action to `useActionState`, the action's function signature changes to receive a new `prevState` or `initialState` parameter as its first argument.
- `useActionState` is a React hook and therefore must be used in a Client Component.

```tsx filename="app/actions.ts" switcher
'use server'
Expand All @@ -385,20 +385,20 @@ export async function createUser(prevState, formData) {
}
```

Then, you can pass your action to the `useFormState` hook and use the returned `state` to display an error message.
Then, you can pass your action to the `useActionState` hook and use the returned `state` to display an error message.

```tsx filename="app/ui/signup.tsx" switcher
'use client'

import { useFormState } from 'react-dom'
import { useActionState } from 'react'
import { createUser } from '@/app/actions'

const initialState = {
message: '',
}

export function Signup() {
const [state, formAction] = useFormState(createUser, initialState)
const [state, formAction] = useActionState(createUser, initialState)

return (
<form action={formAction}>
Expand All @@ -417,15 +417,15 @@ export function Signup() {
```jsx filename="app/ui/signup.js" switcher
'use client'

import { useFormState } from 'react-dom'
import { useActionState } from 'react'
import { createUser } from '@/app/actions'

const initialState = {
message: '',
}

export function Signup() {
const [state, formAction] = useFormState(createUser, initialState)
const [state, formAction] = useActionState(createUser, initialState)

return (
<form action={formAction}>
Expand Down Expand Up @@ -739,7 +739,7 @@ export async function createTodo(prevState, formData) {
> **Good to know:**
>
> - Aside from throwing the error, you can also return an object to be handled by `useFormState`. See [Server-side validation and error handling](#server-side-validation-and-error-handling).
> - Aside from throwing the error, you can also return an object to be handled by `useActionState`. See [Server-side validation and error handling](#server-side-validation-and-error-handling).
### Revalidating data
Expand Down Expand Up @@ -1002,5 +1002,5 @@ For more information on Server Actions, check out the following React docs:
- [`"use server"`](https://react.dev/reference/react/use-server)
- [`<form>`](https://react.dev/reference/react-dom/components/form)
- [`useFormStatus`](https://react.dev/reference/react-dom/hooks/useFormStatus)
- [`useFormState`](https://react.dev/reference/react-dom/hooks/useFormState)
- [`useActionState`](https://react.dev/reference/react/useActionState)
- [`useOptimistic`](https://react.dev/reference/react/useOptimistic)
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,7 @@ The cache is stored in the browser's temporary memory. Two factors determine how

While a page refresh will clear **all** cached segments, the automatic invalidation period only affects the individual segment from the time it was prefetched.

> **Note**: There is [experimental support](/docs/app/api-reference/next-config-js/staleTimes) for configuring these values as of This configuration option is available as of [v14.2.0](https://github.com/vercel/next.js/releases/tag/v14.2.0).
> **Note**: There is [experimental support](/docs/app/api-reference/next-config-js/staleTimes) for configuring these values, available as of [v14.2.0](https://github.com/vercel/next.js/releases/tag/v14.2.0).
### Invalidation

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ The examples on this page walk through basic username and password auth for educ

### Sign-up and login functionality

You can use the [`<form>`](https://react.dev/reference/react-dom/components/form) element with React's [Server Actions](/docs/app/building-your-application/rendering/server-components), [`useFormStatus()`](https://react.dev/reference/react-dom/hooks/useFormStatus), and [`useFormState()`](https://react.dev/reference/react-dom/hooks/useFormState) to capture user credentials, validate form fields, and call your Authentication Provider's API or database.
You can use the [`<form>`](https://react.dev/reference/react-dom/components/form) element with React's [Server Actions](/docs/app/building-your-application/rendering/server-components), [`useFormStatus()`](https://react.dev/reference/react-dom/hooks/useFormStatus), and [`useActionState()`](https://react.dev/reference/react/useActionState) to capture user credentials, validate form fields, and call your Authentication Provider's API or database.

Since Server Actions always execute on the server, they provide a secure environment for handling authentication logic.

Expand Down Expand Up @@ -200,16 +200,16 @@ export async function signup(state, formData) {
}
```

Back in your `<SignupForm />`, you can use React's `useFormState()` hook to display validation errors to the user:
Back in your `<SignupForm />`, you can use React's `useActionState()` hook to display validation errors to the user:

```tsx filename="app/ui/signup-form.tsx" switcher highlight={7,15,21,27-36}
'use client'

import { useFormState } from 'react-dom'
import { useActionState } from 'react'
import { signup } from '@/app/actions/auth'

export function SignupForm() {
const [state, action] = useFormState(signup, undefined)
const [state, action] = useActionState(signup, undefined)

return (
<form action={action}>
Expand Down Expand Up @@ -248,11 +248,11 @@ export function SignupForm() {
```jsx filename="app/ui/signup-form.js" switcher highlight={7,15,21,27-36}
'use client'

import { useFormState } from 'react-dom'
import { useActionState } from 'react'
import { signup } from '@/app/actions/auth'

export function SignupForm() {
const [state, action] = useFormState(signup, undefined)
const [state, action] = useActionState(signup, undefined)

return (
<form action={action}>
Expand Down Expand Up @@ -290,10 +290,11 @@ export function SignupForm() {

You can also use the `useFormStatus()` hook to handle the pending state on form submission:

```tsx filename="app/ui/signup-form.tsx" highlight={7} switcher
```tsx filename="app/ui/signup-form.tsx" highlight={6} switcher
'use client'

import { useFormStatus, useFormState } from 'react-dom'
import { useActionState } from 'react'
import { useFormStatus } from 'react-dom'

export function SignupButton() {
const { pending } = useFormStatus()
Expand All @@ -306,10 +307,11 @@ export function SignupButton() {
}
```

```jsx filename="app/ui/signup-form.js" highlight={7} switcher
```jsx filename="app/ui/signup-form.js" highlight={6} switcher
'use client'

import { useFormStatus, useFormState } from 'react-dom'
import { useActionState } from 'react'
import { useFormStatus } from 'react-dom'

export function SignupButton() {
const { pending } = useFormStatus()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -428,9 +428,9 @@ export const metadata = {

#### Default value

If not configured, `metadataBase` has a **default value**
If not configured, `metadataBase` has a **default value**.

- When [`VERCEL_URL`](https://vercel.com/docs/concepts/projects/environment-variables/system-environment-variables#:~:text=.-,VERCEL_URL,-The%20domain%20name) is detected: `https://${process.env.VERCEL_URL}` otherwise it falls back to `http://localhost:${process.env.PORT || 3000}`.
- When [`VERCEL_PROJECT_PRODUCTION_URL`](https://vercel.com/docs/concepts/projects/environment-variables/system-environment-variables) or [`VERCEL_URL`](https://vercel.com/docs/concepts/projects/environment-variables/system-environment-variables) is detected, it will be used as the **default value**, otherwise it falls back to `http://localhost:${process.env.PORT || 3000}`. This allows Open Graph images to work on both preview and production deployments.
- When overriding the default, we recommend using environment variables to compute the URL. This allows configuring a URL for local development, staging, and production environments.

#### URL Composition
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ revalidatePath(path: string, type?: 'page' | 'layout'): void;
```

- `path`: Either a string representing the filesystem path associated with the data you want to revalidate (for example, `/product/[slug]/page`), or the literal route segment (for example, `/product/123`). Must be less than 1024 characters. This value is case-sensitive.
- `type`: (optional) `'page'` or `'layout'` string to change the type of path to revalidate. If `path` contains a dynamic segment (for example, `/product/[slug]/page`), this parameter is required.
- `type`: (optional) `'page'` or `'layout'` string to change the type of path to revalidate. If `path` contains a dynamic segment (for example, `/product/[slug]/page`), this parameter is required. If path refers to the literal route segment, e.g., `/product/1` for a dynamic page (e.g., `/product/[slug]/page`), you should not provide `type`.

## Returns

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
title: serverComponentsExternalPackages
title: serverExternalPackages
description: Opt-out specific dependencies from the Server Components bundling and use native Node.js `require`.
---

Expand All @@ -10,9 +10,7 @@ If a dependency is using Node.js specific features, you can choose to opt-out sp
```js filename="next.config.js"
/** @type {import('next').NextConfig} */
const nextConfig = {
experimental: {
serverComponentsExternalPackages: ['@acme/ui'],
},
serverExternalPackages: ['@acme/ui'],
}

module.exports = nextConfig
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
title: bundlePagesRouterDependencies
description: Enable automatic dependency bundling for Pages Router
---

Enable automatic server-side dependency bundling for Pages Router applications. Matches the automatic dependency bundling in App Router.

```js filename="next.config.js"
/** @type {import('next').NextConfig} */
const nextConfig = {
bundlePagesRouterDependencies: true,
}

module.exports = nextConfig
```

Explicitly opt-out certain packages from being bundled using the [`serverExternalPackages`](/docs/pages/api-reference/next-config-js/serverExternalPackages) option.
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
---
title: serverExternalPackages
description: Opt-out specific dependencies from the dependency bundling enabled by `bundlePagesRouterDependencies`.
---

Opt-out specific dependencies from being included in the automatic bundling of the [`bundlePagesRouterDependencies`](/docs/pages/api-reference/next-config-js/bundlePagesRouterDependencies) option.

These pages will then use native Node.js `require` to resolve the dependency.

```js filename="next.config.js"
/** @type {import('next').NextConfig} */
const nextConfig = {
serverExternalPackages: ['@acme/ui'],
}

module.exports = nextConfig
```

Next.js includes a [short list of popular packages](https://github.com/vercel/next.js/blob/canary/packages/next/src/lib/server-external-packages.json) that currently are working on compatibility and automatically opt-ed out:

- `@appsignal/nodejs`
- `@aws-sdk/client-s3`
- `@aws-sdk/s3-presigned-post`
- `@blockfrost/blockfrost-js`
- `@highlight-run/node`
- `@jpg-store/lucid-cardano`
- `@libsql/client`
- `@mikro-orm/core`
- `@mikro-orm/knex`
- `@node-rs/argon2`
- `@node-rs/bcrypt`
- `@prisma/client`
- `@react-pdf/renderer`
- `@sentry/profiling-node`
- `@swc/core`
- `argon2`
- `autoprefixer`
- `aws-crt`
- `bcrypt`
- `better-sqlite3`
- `canvas`
- `cpu-features`
- `cypress`
- `eslint`
- `express`
- `firebase-admin`
- `isolated-vm`
- `jest`
- `jsdom`
- `libsql`
- `mdx-bundler`
- `mongodb`
- `mongoose`
- `next-mdx-remote`
- `next-seo`
- `node-pty`
- `node-web-audio-api`
- `oslo`
- `pg`
- `playwright`
- `postcss`
- `prettier`
- `prisma`
- `puppeteer-core`
- `puppeteer`
- `rimraf`
- `sharp`
- `shiki`
- `sqlite3`
- `tailwindcss`
- `ts-node`
- `typescript`
- `vscode-oniguruma`
- `undici`
- `webpack`
- `websocket`
- `zeromq`
5 changes: 3 additions & 2 deletions examples/next-forms/app/add-form.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"use client";

import { useFormState, useFormStatus } from "react-dom";
import { useActionState } from "react";
import { useFormStatus } from "react-dom";
import { createTodo } from "@/app/actions";

const initialState = {
Expand All @@ -18,7 +19,7 @@ function SubmitButton() {
}

export function AddForm() {
const [state, formAction] = useFormState(createTodo, initialState);
const [state, formAction] = useActionState(createTodo, initialState);

return (
<form action={formAction}>
Expand Down
5 changes: 3 additions & 2 deletions examples/next-forms/app/delete-form.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"use client";

import { useFormState, useFormStatus } from "react-dom";
import { useActionState } from "react";
import { useFormStatus } from "react-dom";
import { deleteTodo } from "@/app/actions";

const initialState = {
Expand All @@ -18,7 +19,7 @@ function DeleteButton() {
}

export function DeleteForm({ id, todo }: { id: number; todo: string }) {
const [state, formAction] = useFormState(deleteTodo, initialState);
const [state, formAction] = useActionState(deleteTodo, initialState);

return (
<form action={formAction}>
Expand Down
2 changes: 1 addition & 1 deletion examples/with-emotion/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"start": "next start"
},
"dependencies": {
"@emotion/cache": "11.10.4",
"@emotion/cache": "11.11.0",
"@emotion/react": "11.10.4",
"@emotion/styled": "11.10.4",
"next": "latest",
Expand Down
6 changes: 4 additions & 2 deletions examples/with-fauna/components/EntryForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
import cn from "classnames";
import { createEntryAction } from "@/actions/entry";
// @ts-ignore
import { useFormState, useFormStatus } from "react-dom";
import { useActionState } from "react";
// @ts-ignore
import { useFormStatus } from "react-dom";
import LoadingSpinner from "@/components/LoadingSpinner";
import SuccessMessage from "@/components/SuccessMessage";
import ErrorMessage from "@/components/ErrorMessage";
Expand All @@ -20,7 +22,7 @@ const initialState = {
};

export default function EntryForm() {
const [state, formAction] = useFormState(createEntryAction, initialState);
const [state, formAction] = useActionState(createEntryAction, initialState);
const { pending } = useFormStatus();

return (
Expand Down
2 changes: 1 addition & 1 deletion lerna.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,5 @@
"registry": "https://registry.npmjs.org/"
}
},
"version": "14.3.0-canary.40"
"version": "14.3.0-canary.47"
}

0 comments on commit 5605fd0

Please sign in to comment.