Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Form examples · Patterns

Contact Form for React

A contact form with name, email, a subject select and a message textarea under a Get in touch heading.

Framework
UI library

The form behind every Contact us page: name, email, a subject to route the request and a message. The Input, Select and Textarea each sit in a Field with its FieldLabel and FieldError, wired to React Hook Form by a Controller, and a Zod schema checks all four before Send Message submits. Use it for support requests, sales inquiries or feedback.

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 each contact field check?

name is .min(2) with "Name must be at least 2 characters.", email is z.email("Please enter a valid email address."), and message is .min(10) with "Message must be at least 10 characters."

What shows if subject is left unset?

subject starts as "" and must pass .min(1, "Please select a subject."), so Send Message without one marks the field invalid and shows that message. Until then the trigger shows "Select a subject".

How is the subject select wired?

The options are General Inquiry, Technical Support, Sales, Feedback and Other, stored as general, support, sales, feedback and other. Select takes items, value={field.value || null}, and onValueChange stores the next value or "".

How is the message textarea set up?

The Textarea has rows={5}, resize-none and the placeholder "How can we help you?", with the FieldDescription "Please provide as much detail as possible."

What is the text above the fields?

An h2 Get in touch and a muted line, "We'll get back to you within 24 hours", in a flex flex-col gap-2 block at the top of the FieldGroup.

What does Send Message submit?

Send Message is a full-width type="submit" button. form.handleSubmit(onSubmit) logs { email, message, name, subject } to the console once the schema passes. Send it to your API or a form service from there.