Blog · Getting forms right
Submitting Without Losing the Page
How to submit a form without reloading the page and without losing the visitor's work: the four states a submit button owes the visitor, why typed text must survive every failure, and how to make success heard by screen readers as well as seen.
A reload can erase what the visitor typed
With a traditional form, the visitor presses the button, the browser throws away the page they were on, and a new page arrives saying what happened. When everything works, that's fine. When something fails (a validation error, a server problem, a dropped connection), the visitor gets whatever page the server sends back, and in too many setups that page arrives with every field empty. Ten minutes of careful writing is gone, replaced by a sentence about an invalid phone number.
That's the real reason to submit without leaving the page. When the page stays, the visitor's work stays with it. The paragraphs they typed, the options they chose, and their place on the page all survive whatever happens next.
The goal is certainty
Submitting in place takes something away, though. Loading a new page, for all its faults, was clear evidence that something happened. Remove it without putting anything in its place and you get the worst version of the form. The visitor clicks, nothing on the screen changes, and they're left staring at it. Did it send? They click again. Now you may have two submissions, or none, and they still don't know.
So the real question is whether every stage of the submission is obvious to the visitor. A form that submits in place has to show on screen what loading a new page used to show. That is the actual work.
When the script fails, the form must not
Submitting in place depends on JavaScript, the least dependable layer of any page. Strict corporate networks block scripts, an unrelated error elsewhere on the page can break them, and on a bad connection they may never arrive. If your form only works when its script works, it fails silently, and it fails for the visitors least able to figure out why.
Build a real form underneath. It should submit the traditional way on its own, with the in-page behavior added on top when the script loads and runs. If the script works, visitors get the calm version with no reload. If it doesn't, the form still submits and a plain confirmation page still answers. Nobody is left pressing a button that does nothing.
Treat the network the same way. When a submission times out partway, the form can't know whether the message arrived, so it should say so plainly, keep the visitor's text, and offer to try again. Organizations that show 'success' when the real answer is 'unknown' end up apologizing for messages they never received.