# How to Use Pre-Built Validation Schemas (loginSchema & registerSchema) in refine-shadcn

> Learn to use loginSchema and registerSchema in refine-shadcn. Import validation schemas, pass to zodResolver, and get typed form data for auth without custom Zod logic.

- Repository: [Ferdi ÜNAL/refine-shadcn](https://github.com/ferdiunal/refine-shadcn)
- Tags: how-to-guide
- Published: 2026-03-01

---

**Import `loginSchema` or `registerSchema` from `@/lib/validation`, pass them to `zodResolver` in your `useForm` hook, and receive fully-typed, validated form data for authentication flows without writing custom Zod logic.**

The `refine-shadcn` repository provides production-ready authentication components backed by strict validation rules. These rules live as **Zod** schemas in [`packages/auth/src/lib/validation.ts`](https://github.com/ferdiunal/refine-shadcn/blob/main/packages/auth/src/lib/validation.ts), offering a single source of truth for login and registration validation that propagates TypeScript types throughout your application.

## Where the Pre-Built Schemas Live

All validation logic is centralized in [`packages/auth/src/lib/validation.ts`](https://github.com/ferdiunal/refine-shadcn/blob/main/packages/auth/src/lib/validation.ts). This file exports two primary schemas and their inferred types:

- `loginSchema` – Validates email format and password length (minimum 6 characters)
- `registerSchema` – Validates name, email, password strength, password confirmation matching, and terms acceptance
- `LoginFormData` – TypeScript type derived from `loginSchema`
- `RegisterFormData` – TypeScript type derived from `registerSchema`

The repository exposes these through a path alias `@/lib/validation`, allowing you to import them cleanly from any component without relative path navigation.

## Understanding the Schema Definitions

### Login Validation Rules

The `loginSchema` enforces two fields with specific constraints. According to the source in [`packages/auth/src/lib/validation.ts`](https://github.com/ferdiunal/refine-shadcn/blob/main/packages/auth/src/lib/validation.ts), it requires a valid email address and a password of at least 6 characters:

```typescript
// packages/auth/src/lib/validation.ts
export const loginSchema = z.object({
  email: z.string().email("Invalid email address").min(1, "Email is required"),
  password: z.string().min(6, "Password must be at least 6 characters").min(1, "Password is required"),
});

```

### Registration Validation Rules

The `registerSchema` handles complex multi-field validation including password confirmation. It uses Zod's `.refine()` method to ensure `confirmPassword` matches `password` and that `acceptTerms` is true:

```typescript
// packages/auth/src/lib/validation.ts
export const registerSchema = z.object({
  name: z.string().min(2, "Name must be at least 2 characters"),
  email: z.string().email("Invalid email address"),
  password: z.string().min(8, "Password must be at least 8 characters"),
  confirmPassword: z.string(),
  acceptTerms: z.boolean(),
}).refine((data) => data.password === data.confirmPassword, {
  message: "Passwords don't match",
  path: ["confirmPassword"],
}).refine((data) => data.acceptTerms === true, {
  message: "You must accept the terms",
  path: ["acceptTerms"],
});

```

## Integrating with react-hook-form

To activate validation in your components, wire the schemas into **react-hook-form** using `@hookform/resolvers/zod`. This bridges Zod's parsing logic with the form's state management.

### Basic Login Form Setup

Import the schema and type, then pass them to `useForm`:

```tsx
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { loginSchema, type LoginFormData } from "@/lib/validation";

const form = useForm<LoginFormData>({
  resolver: zodResolver(loginSchema),
  defaultValues: { email: "", password: "" },
});

```

### Basic Registration Form Setup

The pattern is identical for registration, using the richer `registerSchema`:

```tsx
import { registerSchema, type RegisterFormData } from "@/lib/validation";

const form = useForm<RegisterFormData>({
  resolver: zodResolver(registerSchema),
  defaultValues: {
    name: "",
    email: "",
    password: "",
    confirmPassword: "",
    acceptTerms: false,
  },
});

```

## Complete Component Examples

### Login Form Implementation

The [`packages/auth/src/components/login-form.tsx`](https://github.com/ferdiunal/refine-shadcn/blob/main/packages/auth/src/components/login-form.tsx) file demonstrates the canonical implementation. It combines the schema with shadcn/ui form primitives to render validation errors automatically:

```tsx
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { loginSchema, type LoginFormData } from "@/lib/validation";
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@ferdiunal/refine-shadcn/ui/form";
import { Input } from "@ferdiunal/refine-shadcn/ui/input";
import { Button } from "@ferdiunal/refine-shadcn/ui/button";

export function LoginForm({ onSubmit }: { onSubmit: (data: LoginFormData) => void }) {
  const form = useForm<LoginFormData>({
    resolver: zodResolver(loginSchema),
    defaultValues: { email: "", password: "" },
  });

  return (
    <Form {...form}>
      <form onSubmit={form.handleSubmit(onSubmit)} className="space-y-4">
        <FormField
          control={form.control}
          name="email"
          render={({ field }) => (
            <FormItem>
              <FormLabel>Email</FormLabel>
              <FormControl>
                <Input type="email" placeholder="you@example.com" {...field} />
              </FormControl>
              <FormMessage />
            </FormItem>
          )}
        />
        <FormField
          control={form.control}
          name="password"
          render={({ field }) => (
            <FormItem>
              <FormLabel>Password</FormLabel>
              <FormControl>
                <Input type="password" {...field} />
              </FormControl>
              <FormMessage />
            </FormItem>
          )}
        />
        <Button type="submit" disabled={form.formState.isSubmitting}>
          Sign In
        </Button>
      </form>
    </Form>
  );
}

```

### Registration Form Implementation

The registration form in [`packages/auth/src/components/register-form.tsx`](https://github.com/ferdiunal/refine-shadcn/blob/main/packages/auth/src/components/register-form.tsx) follows the same architecture but includes additional fields for name, confirm password, and terms acceptance. The `FormMessage` component automatically displays errors from the schema's `.refine()` calls, such as mismatched passwords or unchecked terms boxes.

## Customizing the Schemas

Because validation is centralized in [`packages/auth/src/lib/validation.ts`](https://github.com/ferdiunal/refine-shadcn/blob/main/packages/auth/src/lib/validation.ts), you can modify authentication rules globally. For example, to require stronger passwords across your entire application:

1. Open [`packages/auth/src/lib/validation.ts`](https://github.com/ferdiunal/refine-shadcn/blob/main/packages/auth/src/lib/validation.ts)
2. Update the password field in both schemas:
   ```typescript
   password: z.string().min(12, "Password must be at least 12 characters").regex(/[A-Z]/, "Must contain uppercase"),
   ```

3. Save the file—all forms using these schemas immediately enforce the new rules without component-level changes.

## Summary

- **Centralized location**: All pre-built validation schemas live in [`packages/auth/src/lib/validation.ts`](https://github.com/ferdiunal/refine-shadcn/blob/main/packages/auth/src/lib/validation.ts) and export via `@/lib/validation`.
- **Two primary exports**: `loginSchema` (email + 6-char password) and `registerSchema` (name, email, password match, terms).
- **Type inference**: Import `LoginFormData` and `RegisterFormData` to type your form hooks and submit handlers.
- **react-hook-form integration**: Use `zodResolver(loginSchema)` in `useForm` to activate validation.
- **Automatic UI feedback**: Form primitives from `@ferdiunal/refine-shadcn/ui` consume the validation state and render errors via `<FormMessage />`.

## Frequently Asked Questions

### How do I access the validated data after form submission?

When `form.handleSubmit` executes, react-hook-form passes the validated data to your callback function with the exact shape defined by the schema. For example, if using `registerSchema`, your `onSubmit` handler receives a `RegisterFormData` object containing `{ name, email, password, confirmPassword, acceptTerms }`, all guaranteed to meet the validation rules defined in [`packages/auth/src/lib/validation.ts`](https://github.com/ferdiunal/refine-shadcn/blob/main/packages/auth/src/lib/validation.ts).

### Can I extend the pre-built schemas for additional fields?

Yes. Import the base schema and use Zod's `.extend()` method to add new fields, or compose a new schema that merges the existing one. Because the schemas are standard Zod objects, you can chain methods like `.pick()`, `.omit()`, or `.merge()` to create variations for different authentication flows while keeping the core validation logic intact.

### What happens if I don't use the default UI components?

The schemas work with any react-hook-form implementation. Even without `@ferdiunal/refine-shadcn/ui` primitives, passing `zodResolver(loginSchema)` to `useForm` still provides type-safe validation state via `form.formState.errors`. You can display these errors manually by accessing `form.formState.errors.email?.message` or similar properties in your custom input components.

### Do these schemas support internationalization?

The raw schemas in [`packages/auth/src/lib/validation.ts`](https://github.com/ferdiunal/refine-shadcn/blob/main/packages/auth/src/lib/validation.ts) contain hardcoded English error messages. To support multiple languages, either override the error messages when instantiating the resolver or wrap the validation logic in a factory function that accepts translation helpers. The repository's own login and register components demonstrate integration with translation hooks for message customization.