conformValibotMessage
A set of custom messages to control the validation behavior. This is useful if you need async validation for one of the fields.
#Options
conformValibotMessage.VALIDATION_SKIPPED
This message is used to indicate that the validation is skipped and Conform should use the previous result instead.
conformValibotMessage.VALIDATION_UNDEFINED
This message is used to indicate that the validation is not defined and Conform should fallback to server validation.
#Example
You can skip an validation to use the previous result. On client validation, you can indicate the validation is not defined to fallback to server validation.
1import type { Intent } from '@conform-to/react';
2import { useForm } from '@conform-to/react';
3import { parseWithValibot, conformValibotMessage } from '@conform-to/valibot';
4import {
5 check,
6 forward,
7 forwardAsync,
8 object,
9 partialCheck,
10 partialCheckAsync,
11 pipe,
12 pipeAsync,
13 string,
14} from 'valibot';
15
16function createBaseSchema(intent: Intent | null) {
17 return object({
18 email: pipe(
19 string('Email is required'),
20 // When not validating email, leave the email error as it is.
21 check(
22 () =>
23 intent === null ||
24 (intent.type === 'validate' && intent.payload.name === 'email'),
25 conformValibotMessage.VALIDATION_SKIPPED,
26 ),
27 ),
28 password: string('Password is required'),
29 });
30}
31
32function createServerSchema(
33 intent: Intent | null,
34 options: { isEmailUnique: (email: string) => Promise<boolean> },
35) {
36 return pipeAsync(
37 createBaseSchema(intent),
38 forwardAsync(
39 partialCheckAsync(
40 [['email']],
41 async ({ email }) => options.isEmailUnique(email),
42 'Email is already used',
43 ),
44 ['email'],
45 ),
46 );
47}
48
49function createClientSchema(intent: Intent | null) {
50 return pipe(
51 createBaseSchema(intent),
52 forward(
53 // If email is specified, fallback to server validation to check its uniqueness.
54 partialCheck(
55 [['email']],
56 () => false,
57 conformValibotMessage.VALIDATION_UNDEFINED,
58 ),
59 ['email'],
60 ),
61 );
62}
63
64export async function action({ request }) {
65 const formData = await request.formData();
66 const submission = await parseWithValibot(formData, {
67 schema: (intent) =>
68 createServerSchema(intent, {
69 isEmailUnique: async (email) => {
70 // Query your database to check if the email is unique
71 },
72 }),
73 });
74
75 // Send the submission back to the client if the status is not successful
76 if (submission.status !== 'success') {
77 return submission.reply();
78 }
79
80 // ...
81}
82
83function ExampleForm() {
84 const [form, { email, password }] = useForm({
85 onValidate({ formData }) {
86 return parseWithValibot(formData, {
87 schema: (intent) => createClientSchema(intent),
88 });
89 },
90 });
91
92 // ...
93}