Published on

Email Validation with Zod in React | ZOD Email Validation

Authors
  • Name
    Ripal & Zalak
    Twitter

How to Do Email Validation with Zod ?

1. Validating for Specific Email

import { z } from 'zod'

const LoginSchema = z.object({
  email: z
    .string()
    .min(1, { message: 'This field has to be filled.' })
    .email({ message: 'This is not a valid email.' })
    .refine((e) => e === '[email protected]', {
      message: 'This email is not in our database.',
    }),
})

export default LoginSchema

Explanation:

  • .min(1): Ensures the field is not empty.
  • .email(): Validates email format.
  • .refine(): Adds a custom validation rule to check for a specific email.

2. Validating Against a Dynamic Database

If you need to validate emails dynamically against a database, you can use an asynchronous refinement:

const LoginSchemaAsync = z.object({
  email: z
    .string()
    .min(1, { message: 'This field has to be filled.' })
    .email({ message: 'This is not a valid email.' })
    .refine(
      async (email) => {
        const emails = await fetchEmailsFromDatabase() // Replace with your API call
        return emails.includes(email)
      },
      { message: 'This email is not in our database.' }
    ),
})

Key Points:

  • Use .refine(async) for database-based validation.
  • Avoid fetching large datasets; validate against specific API endpoints for security and performance.

Example Usage in React

Here’s how you can integrate the schema into a React component with react-hook-form:

import { useForm } from 'react-hook-form'
import { zodResolver } from '@hookform/resolvers/zod'
import LoginSchema from './LoginSchema'

const LoginForm = () => {
  const {
    register,
    handleSubmit,
    formState: { errors },
  } = useForm({
    resolver: zodResolver(LoginSchema),
  })

  const onSubmit = (data) => {
    console.log('Submitted data:', data)
  }

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <div>
        <label htmlFor="email">Email:</label>
        <input id="email" type="text" {...register('email')} />
        {errors.email && <p>{errors.email.message}</p>}
      </div>
      <button type="submit">Submit</button>
    </form>
  )
}

export default LoginForm

FAQs

1. Why use Zod for validation?

Zod offers a declarative approach to validation, type safety, and seamless integration with TypeScript and form libraries.

2. Can I use this for validating other fields?

Yes, Zod supports complex validations for strings, numbers, arrays, and even custom types.

3. Is this approach secure for checking user emails?

Perform sensitive validations like email existence checks on the backend. Use frontend validation for user experience improvements only.

4. What are the risks of fetching all emails for validation?

Fetching all user emails can expose sensitive data, consume bandwidth, and degrade performance. Always use secure and efficient APIs for dynamic checks.