Skip to content

Advanced cases

Forms and 422s

Progressive enhancement over router.visit.

Forms are visits. Form progressive-enhances a real <form>. useForm holds field state, errors, processing, and progress. A 422 is still a seed — with errors — so the page can stay put.

Typed JSON writes that are not a page go through server actions and useAction instead.

useForm
const comment = useForm({ body: "" })

comment.post("/p/hello/comments", {
preserveScroll: true,
onSuccess: () => comment.reset(),
})
const comment = useForm({ body: "" })

comment.post("/p/hello/comments", {
preserveScroll: true,
onSuccess: () => comment.reset(),
})
Form
<Form action="/p/hello/comments" method="post" resetOnSuccess>
<textarea name="body"></textarea>
</Form>
<Form action="/p/hello/comments" method="post" resetOnSuccess>
<textarea name="body"></textarea>
</Form>

preserveScroll: "errors" restores scroll only when the seed has errors. preserveState keeps the module mounted so field focus survives the round-trip.