#How to add client-side validation with form actions?
1 messages · Page 1 of 1 (latest)
Hi @exotic sparrow. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:
For basic client-side form validation, you can use HTML validation attributes like required and type="email". These attributes provide immediate feedback to the user and help prevent invalid form submissions.
Here's an example of how you can use these attributes in your form:
<form action={formAction}>
<label htmlFor="email">Email</label>
<input type="text" id="email" name="email" required />
{/* ... */}
</form>
For more advanced validation, you can use a schema validation library like Zod to validate the form fields before mutating the data. Here's an example of how you can use Zod for server-side validation:
import { z } from 'zod'
const schema = z.object({
email: z.string({
invalid_type_error: 'Invalid Email',
}),
})
export default async function createUser(formData: FormData) {
const validatedFields = schema.safeParse({
email: formData.get('email'),
})
// Return early if the form data is invalid
if (!validatedFields.success) {
return {
errors: validatedFields.error.flatten().fieldErrors,
}
}
// Mutate data
}
Once the fields have been validated on the server, you can return a serializable object in your action and use the React useFormState hook to show a message to the user. Here's an example:
'use server'
export async function createUser(prevState: any, formData: FormData) {
// ...
return {
message: 'Please enter a valid email',
}
}
Then, you can pass your action to the useFormState hook and use the returned state to display an error message:
'use client'
import { useFormState } from 'react-dom'
import { createUser } from '@/app/actions'
const initialState = {
message: '',
}
export function Signup() {
const [state, formAction] = useFormState(createUser, initialState)
return (
<form action={formAction}>
<label htmlFor="email">Email</label>
<input type="text" id="email" name="email" required />
{/* ... */}
<p aria-live="polite" className="sr-only">
{state?.message}
</form>
)
}
Remember to always ensure a user is also authorized to perform the action before mutating data.
For more information, you can refer to the following sources:
- Next.js Docs: Server-side validation and error handling (https://nextjs.org/docs/app/building-your-application/data-fetching/server-actions-and-mutations#server-side-validation-and-error-handling)
- Next.js Docs: Form validation (https://nextjs.org/docs/pages/building-your-application/data-fetching/forms-and-mutations#form-validation)
- Next.js Docs: Validate form fields on the server (https://nextjs.org/docs/app/building-your-application/authentication#2-validate-form-fields-on-the-server)