Skip to content

shadcn.io is an independent project built on shadcn/ui

Free

Custom Validation Messages Form for Ark UI

A sign-up form whose username, email, and age rules each answer with their own short custom message.

Username, email, and age each fail with a sentence written for that rule, including an emoji. Username wants 3 to 20 letters, numbers, or underscores. Age must be a number from 13 to 120.

Use it when the stock error text is too blunt. The rules stay in Zod, not in the Input. In React, Ark UI only shows the message.

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.
Use email insteadNo credit card

Usage

<form
  className="w-full max-w-md"
  noValidate
  onSubmit={form.handleSubmit(onSubmit)}
>
  <FieldGroup>
    <Controller
      control={form.control}
      name="username"
      render={({ field, fieldState }) => (
        <Field invalid={fieldState.invalid}>
          <FieldLabel>Username</FieldLabel>
          <Input {...field} placeholder="cool_user123" />
          <FieldDescription>Choose a unique username.</FieldDescription>
          <FieldError>{fieldState.error?.message}</FieldError>
        </Field>
      )}
    />
    <Controller
      control={form.control}
      name="email"
      render={({ field, fieldState }) => (
        <Field invalid={fieldState.invalid}>
          <FieldLabel>Email</FieldLabel>
          <Input {...field} placeholder="you@example.com" type="email" />
          <FieldError>{fieldState.error?.message}</FieldError>
        </Field>
      )}
    />
    <Controller
      control={form.control}
{/* The rest of the file is under Installation. */}

FAQ

Which username messages are in the schema?

.min(3) says "Come on, at least 3 characters! ๐Ÿ˜…", .max(20) says "Whoa there! Keep it under 20 characters. ๐Ÿ›‘", and .regex(/^[a-zA-Z0-9_]+$/) says "Letters, numbers, and underscores only, please! ๐Ÿ”ค". The FieldError shows the first one that fails.

What does a bad email say?

email is z.email("That doesn't look like an email address. ๐Ÿ“ง"). The form sets noValidate, so the browser's own email check doesn't get there first. Only Username has a description: "Choose a unique username."

Which age messages appear?

.min(13) says "You must be at least 13 years old. ๐Ÿšธ" and .max(120) says "Please enter a realistic age. ๐ŸŽ‚". Age is z.number with the error "Age must be a number! ๐Ÿ”ข" for anything that isn't a number.

What does a blank age produce?

age starts as undefined, and clearing the input sets it back to undefined, so a blank age shows "Age must be a number! ๐Ÿ”ข". It never turns into 0.

How is the age input set up?

It's an Input with type="number" and placeholder 25. Instead of spreading field, its onChange stores Number(event.target.value), or undefined when empty, and value is field.value ?? "".

When do these messages show?

mode is the default, so the schema first runs on submit. Sign Up is a type="submit" button, and onSubmit logs { age, email, username }, with age a number, once everything passes.

API Reference

Field

Sets invalid={fieldState.invalid} and orientation="horizontal". The rest is on the Field page.

Input

Sets field, placeholder="cool_user123", placeholder="you@example.com", type="email", name={field.name} and onBlur={field.onBlur}. The rest is on the Input page.

Button

Sets type="submit". The rest is on the Button page.