Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Form examples · Basic Forms

Email Input Form for React

A newsletter form with one email input that checks the address format before it subscribes.

Framework
UI library

Email inputs need format validation to catch typos. This form checks the address with Zod's z.email(), so an address like user@domain fails with "Please enter a valid email address." A Controller connects the Input to React Hook Form inside a Field, with a FieldDescription for the privacy note and a FieldError for the message, and type="email" brings up the email keyboard on phones. Use it for newsletter sign-ups, account creation or contact forms.

Preview

Preview width

Installation

Sign in to get your install command
Free with an account. It carries your token, so the CLI installs everything in one go.

FAQ

What does the email schema check?

email is z.email("Please enter a valid email address."). When it fails, the Field gets invalid and FieldError shows the message. you@example.com is only the placeholder, not a value.

Why is the input type email?

type="email" shows the email keyboard on phones, and the browser also checks the format when the form submits: a malformed address gets the browser's own hint before Zod runs. Add noValidate to the form if you want only the Zod message.

Where is the privacy sentence defined?

FieldDescription renders "We'll never share your email with anyone." It stays visible whether the field is empty, filled or invalid, with the FieldError below it.

How does Subscribe get the address?

The Controller for name="email" spreads field onto the Input, so its value, change, blur and ref go through React Hook Form. FieldLabel htmlFor matches the input's id, email-input-form-email. Subscribe is a type="submit" button, and form.handleSubmit(onSubmit) calls onSubmit with the parsed values.

When does the invalid-email message appear?

mode is unset, so the first check runs on submit. After a failed submit, React Hook Form checks again on every change until the address is valid. An empty string fails with the same message.

What is the field's starting value?

defaultValues sets email to "", so the input is controlled from the first render and the placeholder shows until someone types.