Valibot Schema / conformValibotMessage

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}