← Back to patterns

Form pattern

Using form() with progressive enhancement

Pattern Usage:

// In remote file:
export const testForm = form(
  z.object({
    message: z.string().min(1),
    count: z.coerce.number().default(0)
  }),
  async (data) => {
    // Process form data
    return { success: true, data };
  }
);

// In component:
<form {...testForm.enhance(async ({ submit }) => {
  isSubmitting = true;
  try {
    const result = await submit();
    toast.success('Form submitted!');
  } finally {
    isSubmitting = false;
  }
})}>
  <input name="message" />
  <button type="submit">Submit</button>
</form>

Live Demo:

How it works: Forms use progressive enhancement - they work without JavaScript but enhance with client-side validation and loading states when JS is available. The .enhance() method intercepts submission, handles validation, and provides hooks for loading states. Note the z.coerce.number() which automatically converts the string input to a number.