Validate your fields
During the development of Modular Forms, we paid special attention to input validation. It is one of the core functionalities of the library. You can use our internal validation functions or optionally a schema library such as Zod.
To keep the bundle size small, validation is optional and modular. If your form requires validation, just import the validation functions you need. Another advantage is that you can define the validation globally for the whole form or fine-granularly for each field individually. You can even combine the both methods.
Note that the validation of Modular Forms, except for server actions, takes place in the browser and can be manipulated by the user. Make sure that the values are validated again on the server before you process them or store them in your database.
Validation functions
With our internal validation functions you can reduce your bundle size to a minimum and also achieve unprecedented performance. You can validate almost anything with one line of code. Be it an email, URL or the MIME type of a file.
With our validation functions you define the validation next to your fields via the validate
property. Thus, things are together that belong together. This has a big impact on the DX.
Login form example
In the following example we first use required
to make the input mandatory and then email
to check the formatting and minLength
to check the number of characters.
Note that if you do not add
required
, the input will only be validated if a value is present. In this case an empty string or list will not cause an error.
Also you have the possibility to set your own error message and access the current error via the render function of the Field
component. An overview of all validation functions can be found in our API reference.
import { createForm, email, minLength, required } from '@modular-forms/solid';
type LoginForm = {
email: string;
password: string;
};
export default function App() {
const [loginForm, { Form, Field }] = createForm<LoginForm>();
return (
<Form>
<Field
name="email"
validate={[
required('Please enter your email.'),
email('The email address is badly formatted.'),
]}
>
{(field, props) => (
<>
<input {...props} type="email" required />
{field.error && <div>{field.error}</div>}
</>
)}
</Field>
<Field
name="password"
validate={[
required('Please enter your password.'),
minLength(8, 'You password must have 8 characters or more.'),
]}
>
{(field, props) => (
<>
<input {...props} type="password" required />
{field.error && <div>{field.error}</div>}
</>
)}
</Field>
<input type="submit" />
</Form>
);
}
Times of validation
By default, the first validation is done when the form is submitted for the first time and from there on, a revalidation is triggered after each user input. You can change this behavior using the validateOn
and revalidateOn
option of the createForm
primitive.
Schema validation
For maximum flexibility, you can also use your familiar schema library for form validation. We currently offer adapters for Zod. Please create an issue if you want us to add more adapters.
Use zodForm
to define the validation for the whole form and zodField
for a single field. Below is the same login form as in the example above. Instead of our validation functions, Zod is used now.
import { createForm, zodForm } from '@modular-forms/solid';
import { z } from 'zod';
const schema = z.object({
email: z
.string()
.min(1, 'Please enter your email.')
.email('The email address is badly formatted.'),
password: z
.string()
.min(1, 'Please enter your password.')
.min(8, 'You password must have 8 characters or more.'),
});
export default function App() {
const [loginForm, { Form, Field }] = createForm<z.infer<typeof schema>>({
validate: zodForm(schema),
});
return (
<Form>
<Field name="email">
{(field, props) => (
<>
<input {...props} type="email" required />
{field.error && <div>{field.error}</div>}
</>
)}
</Field>
<Field name="password">
{(field, props) => (
<>
<input {...props} type="password" required />
{field.error && <div>{field.error}</div>}
</>
)}
</Field>
<input type="submit" />
</Form>
);
}