@jmondi/zod-friendly-forms@2.0.0Built and signed on GitHub ActionsBuilt and signed on GitHub Actions
Validate forms with ease using Zod and get user-friendly error messages or valid typed data, compatible with any framework on both server and client side.
Zod Friendly Forms
Returns an object containing errors
and validData
. The errors
object
contains user-friendly error messages, making it easy to display validation
errors to the user, while the validData
object contains the typed and valid
data from the schema. This library can be used in any framework, both on the
server or client side and it allows for easy validation and handling of form
submissions.
Install (npm)
pnpm add zod pnpm dlx jsr add @jmondi/zod-friendly-forms
Deno
deno add @jmondi/zod-friendly-forms
Usage
Create a [zod] schema.
import { z } from "zod"; const schema = z.object({ email: z.string().email(), });
When you're ready to validate your input data, go ahead and run the parseForm
function. If there are any errors, they will be available by input key.
import { parseForm } from "@jmondi/zod-friendly-forms"; const data = { email: "invalid-email", }; const { errors } = parseForm({ schema, data }); errors; // { // email: "Invalid email", // }
If errors are undefined, the input was valid. A returned validData
object will
be typed with your response.
import { parseForm } from "@jmondi/zod-friendly-forms"; const data = { email: "bob@example.com", }; const { errors, validData } = parseForm({ schema, data }); errors; // undefined validData; // { // email: "bob@example.com", // }
You can use the builtin FormData
or URLSearchParams
object.
const data = new FormData(); data.append("email", "invalid-email"); const { errors } = parseForm({ schema, data }); errors; // { // email: "Invalid email", // }
const schema = z.object({ user: z.object({ email: z.string().email(), }), }); const data = { user: { email: "bob", }, }; const { errors } = parseForm({ schema: RegisterSchema, data }, options); errors; // { // "user.email": "Invalid Email Address", // }
Examples
This library will work on the server or client, in any framework.
Svelte Examples
<script lang="ts"> import { z } from "zod"; import { parseForm } from "@jmondi/zod-friendly-forms"; import { handleLogin } from "./my-login-function"; let errors; const LoginSchema = z.object({ email: z.string().email(), password: z.string().min(8), }); const loginForm = { email: "", password: "", }; async function submit() { let { data, errors } = await parseForm<typeof LoginSchema>({ schema: LoginSchema, data: loginForm }); if (!errors) await handleLogin(data); } </script> <form on:submit|preventDefault="{submit}"> <label for="email">Email {#if errors?.email}<span class="error">{errors.email}</span>{/if} <input id="email" name="email" type="email" required="required" bind:value="{loginForm.email}" /> </label> <label for="password">Password {#if errors?.password}<span class="error">{errors.password}</span>{/if} <input id="password" name="password" type="password" required="required" bind:value="{loginForm.password}" /> </label> <footer class="form-submit"> <button type="submit">Submit</button> </footer> </form>
React Example
import React, { useState } from "react"; import { z } from "zod"; import { parseForm } from "@jmondi/zod-friendly-forms"; import { handleLogin } from "./my-login-function"; const LoginSchema = z.object({ email: z.string().email(), password: z.string().min(8), rememberMe: z.boolean(), }); const LoginForm = () => { const [formData, setFormData] = useState({ email: "", password: "", rememberMe: false, }); const [errors, setErrors] = useState({}); const handleSubmit = async (e) => { e.preventDefault(); let { data, errors } = await parseForm({ schema: LoginSchema, data: formData, }); if (!errors) await handleLogin(data); setErrors(errors); }; return ( <form onSubmit={handleSubmit}> <label htmlFor="email"> Email {errors.email && <span className="error">{errors.email}</span>} <input id="email" name="email" type="email" required value={formData.email} onChange={(e) => setFormData({ ...formData, email: e.target.value })} /> </label> <label htmlFor="password"> Password {errors.password && <span className="error">{errors.password}</span>} <input id="password" name="password" type="password" required value={formData.password} onChange={(e) => setFormData({ ...formData, password: e.target.value })} /> </label> <label htmlFor="rememberMe"> Remember Me <input id="rememberMe" type="checkbox" checked={formData.rememberMe} onChange={(e) => setFormData({ ...formData, rememberMe: e.target.checked })} /> </label> <footer className="form-submit"> <button type="submit">Submit</button> </footer> </form> ); };
Vue 3 Example
<template> <form @submit.prevent="submit"> <label for="email">Email <span class="error" v-if="errors.email">{{ errors.email }}</span> <input id="email" name="email" type="email" required v-model="formData.email" /> </label> <label for="password">Password <span class="error" v-if="errors.password">{{ errors.password }}</span> <input id="password" name="password" type="password" required v-model="formData.password" /> </label> <label for="rememberMe">Remember Me <input id="rememberMe" type="checkbox" v-model="formData.rememberMe" /> </label> <footer class="form-submit"> <button type="submit">Submit</button> </footer> </form> </template> <script> import { z } from 'zod'; import { parseForm } from 'zod-ff'; import { handleLogin } from './my-login-function'; const LoginSchema = z.object({ email: z.string().email(), password: z.string().min(8), rememberMe: z.boolean(), }); export default { data() { return { formData: { email: "", password: "", rememberMe: false, }, errors: {} }; }, methods: { async submit() { let { data, errors } = await parseForm({ schema: LoginSchema, data: this.formData }); if (!errors) await handleLogin(data); this.errors = errors; } } }; </script>
Add Package
deno add jsr:@jmondi/zod-friendly-forms
Import symbol
import * as zod_friendly_forms from "@jmondi/zod-friendly-forms";
Import directly with a jsr specifier
import * as zod_friendly_forms from "jsr:@jmondi/zod-friendly-forms";
Add Package
pnpm i jsr:@jmondi/zod-friendly-forms
pnpm dlx jsr add @jmondi/zod-friendly-forms
Import symbol
import * as zod_friendly_forms from "@jmondi/zod-friendly-forms";
Add Package
yarn add jsr:@jmondi/zod-friendly-forms
yarn dlx jsr add @jmondi/zod-friendly-forms
Import symbol
import * as zod_friendly_forms from "@jmondi/zod-friendly-forms";
Add Package
vlt install jsr:@jmondi/zod-friendly-forms
Import symbol
import * as zod_friendly_forms from "@jmondi/zod-friendly-forms";
Add Package
npx jsr add @jmondi/zod-friendly-forms
Import symbol
import * as zod_friendly_forms from "@jmondi/zod-friendly-forms";
Add Package
bunx jsr add @jmondi/zod-friendly-forms
Import symbol
import * as zod_friendly_forms from "@jmondi/zod-friendly-forms";