Form handling with react-hook-form and Zod validation .
1import { z } from 'zod';
2
3export const userSchema = z
4 .object({
5 name: z.string().min(2).max(20),
6 email: z.string().email(),
7 })
8 .strict();
1import { z } from 'zod';
2
3export const userSchema = z
4 .object({
5 name: z.string().min(2).max(20),
6 email: z.string().email(),
7 })
8 .strict();
1import { z } from 'zod';
2
3export const userSchema = z
4 .object({
5 name: z.string().min(2).max(20),
6 email: z.string().email(),
7 })
8 .strict();
1import { z } from 'zod';
2
3export const userSchema = z
4 .object({
5 name: z.string().min(2).max(20),
6 email: z.string().email(),
7 })
8 .strict();
1import { prefix, post, VovkRequest } from 'vovk';
2import vovkZod from 'vovk-zod';
3import { z } from 'zod';
4import { userSchema } from '../../zod';
5
6@prefix('form')
7export default class FormController {
8 @post('create-user', { cors: true })
9 @vovkZod(userSchema)
10 static async createUser(req: VovkRequest<z.infer<typeof userSchema>>) {
11 const { name, email } = await req.json();
12
13 return {
14 success: true,
15 user: { name, email },
16 };
17 }
18}
1import { prefix, post, VovkRequest } from 'vovk';
2import vovkZod from 'vovk-zod';
3import { z } from 'zod';
4import { userSchema } from '../../zod';
5
6@prefix('form')
7export default class FormController {
8 @post('create-user', { cors: true })
9 @vovkZod(userSchema)
10 static async createUser(req: VovkRequest<z.infer<typeof userSchema>>) {
11 const { name, email } = await req.json();
12
13 return {
14 success: true,
15 user: { name, email },
16 };
17 }
18}
1import { prefix, post, VovkRequest } from 'vovk';
2import vovkZod from 'vovk-zod';
3import { z } from 'zod';
4import { userSchema } from '../../zod';
5
6@prefix('form')
7export default class FormController {
8 @post('create-user', { cors: true })
9 @vovkZod(userSchema)
10 static async createUser(req: VovkRequest<z.infer<typeof userSchema>>) {
11 const { name, email } = await req.json();
12
13 return {
14 success: true,
15 user: { name, email },
16 };
17 }
18}
1import { prefix, post, VovkRequest } from 'vovk';
2import vovkZod from 'vovk-zod';
3import { z } from 'zod';
4import { userSchema } from '../../zod';
5
6@prefix('form')
7export default class FormController {
8 @post('create-user', { cors: true })
9 @vovkZod(userSchema)
10 static async createUser(req: VovkRequest<z.infer<typeof userSchema>>) {
11 const { name, email } = await req.json();
12
13 return {
14 success: true,
15 user: { name, email },
16 };
17 }
18}
1'use client';
2import { useState } from 'react';
3import { FormController } from 'vovk-client';
4import { useForm } from 'react-hook-form';
5import type { VovkBody, VovkReturnType } from 'vovk';
6import { zodResolver } from '@hookform/resolvers/zod';
7import { userSchema } from '../../zod';
8
9export default function HookFormExample() {
10 const [response, setResponse] = useState<VovkReturnType<typeof FormController.createUser> | null>(null);
11 const {
12 register,
13 handleSubmit,
14 getValues,
15 formState: { errors },
16 } = useForm<VovkBody<typeof FormController.createUser>>({
17 resolver: zodResolver(userSchema),
18 });
19
20 const onSubmit = async () => {
21 setResponse(
22 await FormController.createUser({
23 body: getValues(),
24 })
25 );
26 };
27
28 return (
29 <form onSubmit={handleSubmit(onSubmit)}>
30 <input type="text" placeholder="Name" {...register('name')} />
31 {errors.name && <p>❌ {errors.name.message}</p>}
32 <input type="text" placeholder="Email" {...register('email')} />
33 {errors.email && <p>❌ {errors.email.message}</p>}
34 <button>Submit</button>
35
36 {response && (
37 <div>
38 <h3>Response</h3>
39 <pre className="text-left">{JSON.stringify(response, null, 2)}</pre>
40 </div>
41 )}
42 </form>
43 );
44}
1'use client';
2import { useState } from 'react';
3import { FormController } from 'vovk-client';
4import { useForm } from 'react-hook-form';
5import type { VovkBody, VovkReturnType } from 'vovk';
6import { zodResolver } from '@hookform/resolvers/zod';
7import { userSchema } from '../../zod';
8
9export default function HookFormExample() {
10 const [response, setResponse] = useState<VovkReturnType<typeof FormController.createUser> | null>(null);
11 const {
12 register,
13 handleSubmit,
14 getValues,
15 formState: { errors },
16 } = useForm<VovkBody<typeof FormController.createUser>>({
17 resolver: zodResolver(userSchema),
18 });
19
20 const onSubmit = async () => {
21 setResponse(
22 await FormController.createUser({
23 body: getValues(),
24 })
25 );
26 };
27
28 return (
29 <form onSubmit={handleSubmit(onSubmit)}>
30 <input type="text" placeholder="Name" {...register('name')} />
31 {errors.name && <p>❌ {errors.name.message}</p>}
32 <input type="text" placeholder="Email" {...register('email')} />
33 {errors.email && <p>❌ {errors.email.message}</p>}
34 <button>Submit</button>
35
36 {response && (
37 <div>
38 <h3>Response</h3>
39 <pre className="text-left">{JSON.stringify(response, null, 2)}</pre>
40 </div>
41 )}
42 </form>
43 );
44}
1'use client';
2import { useState } from 'react';
3import { FormController } from 'vovk-client';
4import { useForm } from 'react-hook-form';
5import type { VovkBody, VovkReturnType } from 'vovk';
6import { zodResolver } from '@hookform/resolvers/zod';
7import { userSchema } from '../../zod';
8
9export default function HookFormExample() {
10 const [response, setResponse] = useState<VovkReturnType<typeof FormController.createUser> | null>(null);
11 const {
12 register,
13 handleSubmit,
14 getValues,
15 formState: { errors },
16 } = useForm<VovkBody<typeof FormController.createUser>>({
17 resolver: zodResolver(userSchema),
18 });
19
20 const onSubmit = async () => {
21 setResponse(
22 await FormController.createUser({
23 body: getValues(),
24 })
25 );
26 };
27
28 return (
29 <form onSubmit={handleSubmit(onSubmit)}>
30 <input type="text" placeholder="Name" {...register('name')} />
31 {errors.name && <p>❌ {errors.name.message}</p>}
32 <input type="text" placeholder="Email" {...register('email')} />
33 {errors.email && <p>❌ {errors.email.message}</p>}
34 <button>Submit</button>
35
36 {response && (
37 <div>
38 <h3>Response</h3>
39 <pre className="text-left">{JSON.stringify(response, null, 2)}</pre>
40 </div>
41 )}
42 </form>
43 );
44}
1'use client';
2import { useState } from 'react';
3import { FormController } from 'vovk-client';
4import { useForm } from 'react-hook-form';
5import type { VovkBody, VovkReturnType } from 'vovk';
6import { zodResolver } from '@hookform/resolvers/zod';
7import { userSchema } from '../../zod';
8
9export default function HookFormExample() {
10 const [response, setResponse] = useState<VovkReturnType<typeof FormController.createUser> | null>(null);
11 const {
12 register,
13 handleSubmit,
14 getValues,
15 formState: { errors },
16 } = useForm<VovkBody<typeof FormController.createUser>>({
17 resolver: zodResolver(userSchema),
18 });
19
20 const onSubmit = async () => {
21 setResponse(
22 await FormController.createUser({
23 body: getValues(),
24 })
25 );
26 };
27
28 return (
29 <form onSubmit={handleSubmit(onSubmit)}>
30 <input type="text" placeholder="Name" {...register('name')} />
31 {errors.name && <p>❌ {errors.name.message}</p>}
32 <input type="text" placeholder="Email" {...register('email')} />
33 {errors.email && <p>❌ {errors.email.message}</p>}
34 <button>Submit</button>
35
36 {response && (
37 <div>
38 <h3>Response</h3>
39 <pre className="text-left">{JSON.stringify(response, null, 2)}</pre>
40 </div>
41 )}
42 </form>
43 );
44}