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.
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 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.