# React Hook Form with Next.js

> Use React Hook Form with Next.js App Router and Server Actions, including Client Components, progressive enhancement, and server validation.

Source: https://react-hook-form.com/integrations/nextjs

Call `useForm` from a Client Component in the Next.js App Router. Submit with [`handleSubmit`](https://react-hook-form.com/docs/useform/handlesubmit), or pass a Server Action to React Hook Form's [`Form` component](https://react-hook-form.com/docs/useform/form).

## Create the Server Action

```tsx
// app/profile/actions.ts
"use server"

export async function updateProfile(formData: FormData) {
  const name = String(formData.get("name") ?? "")
  if (!name) throw new Error("Name is required")

  // Authenticate, validate again, then update the database.
}
```

## Build the Client Component

```tsx
// app/profile/profile-form.tsx
"use client"

import { Form, useForm } from "react-hook-form"
import { updateProfile } from "./actions"

export function ProfileForm() {
  const {
    control,
    register,
    formState: { errors, isSubmitting, isSubmitSuccessful },
  } = useForm<{ name: string }>({ progressive: true })

  return (
    <Form control={control} action={updateProfile}>
      <input {...register("name", { required: "Name is required" })} />
      {errors.name && <p role="alert">{errors.name.message}</p>}
      {errors.root?.server && <p role="alert">Could not save your profile.</p>}
      {isSubmitSuccessful && <p>Profile saved.</p>}
      <button disabled={isSubmitting}>Save</button>
    </Form>
  )
}
```

`progressive: true` forwards compatible validation rules as native HTML attributes, allowing useful validation before hydration. After hydration, React Hook Form manages validation.

## Server validation is still required

Client validation improves feedback but is not a security boundary. Authenticate the request, authorize the operation, and validate every untrusted value inside the Server Action. Map returned field errors with [`setError`](https://react-hook-form.com/docs/useform/seterror) when the server needs to report a specific input.

## Choosing a submission pattern

- Use [`Form`](https://react-hook-form.com/docs/useform/form) for a direct Server Action or conventional API request.
- Use [`handleSubmit`](https://react-hook-form.com/docs/useform/handlesubmit) when you need retries, cancellation, or a data-fetching library.
- Use React's `useActionState` when the action result drives UI beyond React Hook Form's `formState`.

See [Server Actions and useActionState](https://react-hook-form.com/advanced-usage#ServerActionsuseActionState), [Zod validation](https://react-hook-form.com/integrations/zod), and [React 19 forms](https://react-hook-form.com/integrations/react-19).
