Input Validation
Validation patterns with Zod schemas, Edge Function parameter validation, and file upload checks.
Overview
Input validation is critical for security and data integrity. ScaleRocket uses Zod for schema-based validation on both client and server, with additional checks for Edge Functions and file uploads.
Zod Schema Validation
Zod is the recommended validation library. Define schemas and validate data before processing:
Basic Schema
import { z } from "zod";
const userSchema = z.object({
email: z.string().email("Invalid email address"),
password: z.string().min(8, "Password must be at least 8 characters"),
name: z.string().min(1, "Name is required").max(100),
});
type UserInput = z.infer<typeof userSchema>;Validating Input
const result = userSchema.safeParse(formData);
if (!result.success) {
// result.error.flatten() gives a structured error object
const errors = result.error.flatten().fieldErrors;
// { email: ["Invalid email address"], password: ["..."] }
return;
}
// result.data is fully typed and safe to use
const { email, password, name } = result.data;Common Schema Patterns
// Optional field with default
const settingsSchema = z.object({
notifications: z.boolean().default(true),
language: z.enum(["en", "fr", "de"]).default("en"),
});
// String transformations
const slugSchema = z.string().trim().toLowerCase().regex(/^[a-z0-9-]+$/);
// Number constraints
const paginationSchema = z.object({
page: z.coerce.number().int().positive().default(1),
limit: z.coerce.number().int().min(1).max(100).default(20),
});
// Union types
const idSchema = z.union([z.string().uuid(), z.string().cuid()]);Client-Side Form Validation
Validate before submitting to prevent unnecessary API calls:
const handleSubmit = (e: FormEvent) => {
e.preventDefault();
const result = userSchema.safeParse({ email, password, name });
if (!result.success) {
const errors = result.error.flatten().fieldErrors;
setErrors(errors);
return;
}
// Submit validated data
submitForm(result.data);
};Edge Function Parameter Validation
Always validate incoming request bodies in Edge Functions:
import { z } from "zod";
const requestSchema = z.object({
userId: z.string().uuid(),
action: z.enum(["activate", "deactivate"]),
reason: z.string().max(500).optional(),
});
Deno.serve(async (req) => {
let body;
try {
body = await req.json();
} catch {
return new Response(JSON.stringify({ error: "Invalid JSON" }), { status: 400 });
}
const result = requestSchema.safeParse(body);
if (!result.success) {
return new Response(
JSON.stringify({ error: "Validation failed", details: result.error.flatten().fieldErrors }),
{ status: 400 }
);
}
// Use result.data safely
const { userId, action } = result.data;
});File Upload Validation
For admin media uploads and user file attachments, validate before processing:
const MAX_FILE_SIZE = 5 * 1024 * 1024; // 5MB
const ALLOWED_TYPES = ["image/jpeg", "image/png", "image/webp", "application/pdf"];
function validateFile(file: File): string | null {
if (file.size > MAX_FILE_SIZE) {
return `File too large. Maximum size is ${MAX_FILE_SIZE / 1024 / 1024}MB.`;
}
if (!ALLOWED_TYPES.includes(file.type)) {
return `Invalid file type. Allowed: ${ALLOWED_TYPES.join(", ")}`;
}
return null; // valid
}With Zod
const fileSchema = z.object({
name: z.string(),
size: z.number().max(5 * 1024 * 1024, "File exceeds 5MB limit"),
type: z.enum(["image/jpeg", "image/png", "image/webp", "application/pdf"], {
errorMap: () => ({ message: "Unsupported file type" }),
}),
});Validation Checklist
- Validate all form inputs before submission (client-side)
- Validate all Edge Function request bodies (server-side)
- Use
safeParseinstead ofparseto avoid throwing exceptions - Set maximum lengths on string fields to prevent payload abuse
- Validate file size and MIME type before upload
- Never trust client-side validation alone; always re-validate on the server
Tips
- Share Zod schemas between client and server by placing them in a shared package.
- Use
z.coercefor query parameters and form data that arrive as strings. - Combine Zod with React Hook Form using
@hookform/resolvers/zodfor integrated form validation. - Sanitize HTML content (e.g., blog posts) with a library like
dompurifyafter Zod validation.
Done reading? Mark this page as complete.