Why my form clears everything I typed — 3 causes and the fix

You know the symptom. Someone fills in a form, hits Submit, the page blinks — and there's "Please check the fields" at the top. And every field is empty. All of them, including the ones that were fine.
What happens next is predictable: half those people leave. They're not going to work around your validation typo — they close the tab.
Good news: there are only three causes, and each is visible within a couple of minutes.
Cause 1: the server re-rendered the form empty
The most common one. The form submits normally, the server validates, finds a problem and… renders the same page from scratch. It's one template — the same one shown the first time. And the first time, the fields were empty.
How to check. Open devtools, the Network tab, and submit with a deliberate error. If you see a POST that returned a full HTML page, that's your case. Look at your fields in the response: you'll find value="" where someone was just typing.
How to fix. Send the form back filled in, with whatever the person submitted:
<input name="email" value="{{ email }}" />
For <select> restore selected, for checkboxes checked. The GOV.UK Design System treats this as a mandatory part of error handling: show the page again with the fields as the user filled them in. In their words, keeping the data lets people see what went wrong, edit their previous answer and avoid re-entering information.
One exception: password fields usually aren't restored — and that's fine, people expect it.
Cause 2: the form re-rendered on the client
If there's no network request at all and the fields still emptied, your own JavaScript wiped them.
The usual mechanic in frameworks like React: an error flips some state, and the form now renders in a different branch — or its key changed. To the framework that's a different form, not the same one. The old fields are destroyed along with their contents.
How to check. Drop a console.log at the top of the form component. If it prints after Submit and the typed text is gone, the component was recreated.
How to fix. Field values have to live above whatever re-renders: in the parent's state, or in one form object. Then any re-render brings the values back. And don't hide the whole form to show an error — render the error next to it.
Cause 3: Back didn't restore the page
A separate scenario: someone moves to the next screen, presses Back, and lands on an empty form.
Normally the browser restores the previous page whole from memory — that's the bfcache — including the values typed into it. But a page can be kept out of that cache.
How to check. Add a listener and watch what happens on the way back:
window.addEventListener("pageshow", (event) => {
console.log("restored from bfcache:", event.persisted);
});
false after pressing Back means the page was loaded from scratch — so it wasn't allowed into the cache.
How to fix. The two usual culprits:
- An
unloadhandler. The web.dev guidance puts it bluntly: never use theunloadevent, ever. On desktop, Chrome and Firefox make a page with that handler ineligible for bfcache. Usepagehideinstead — it fires in all the same cases. Cache-Control: no-storeon the page itself. Historically browsers won't put such pages in the bfcache. Pages behind a login often carry it "just in case" — check whether this one really needs it.
Do this once and stop losing data
Save a draft as they type — it covers all three causes at once, plus the accidentally closed tab:
form.addEventListener("input", () => {
const data = Object.fromEntries(new FormData(form));
localStorage.setItem("draft", JSON.stringify(data));
});
Restore it on page load, and clear the key after a successful submit so the draft doesn't resurface next time.
While you're there, check the error text itself: "Please check the fields" tells nobody anything. It needs to say which field and what's wrong with it. And if the form is long, that's also a reason to split it into steps — losing one screen out of four stings a lot less.
Short story-lessons, an agent simulator and daily practice — in our mobile app. Free.
Why do the fields only empty sometimes?
Most likely cause 3: it only shows up when going Back, and browsers behave differently about it. Causes 1 and 2 reproduce every time — if an error clears the form on every attempt, look there.
Can I fix this without touching the server?
If the form submits as a plain POST with a page reload, no — the server is what returns the values. But a localStorage draft always works and needs nothing beyond a few client-side lines. It's a decent stopgap while you fix the real cause.





