Forms are harder than they look
The double submit, the lost draft, and the validation that runs in the wrong place.
A form looks like the simplest thing on a page and contains more edge cases than anything else on it. Three in particular account for most real complaints.
The double submit
The user clicks Submit. Nothing visibly happens because the request takes two seconds. They click again. You now have two orders. The fix is to disable the button the instant it is pressed and to show that something is happening, and, for anything that matters, to make the operation idempotent on the server, exactly as covered in the background jobs course.
The lost draft
Someone writes four paragraphs, their session expires, they submit, and it all disappears. This is infuriating and entirely preventable: keep long-form input in browser storage as it is typed, and restore it if they come back. It costs very little and it is the difference between an annoyance and a lost user.
What happens if they press submit twice?
They will. Fast connections hide it, slow ones do not, and the consequences land on whoever has the worst network.
What to remember
- Disable submit immediately and make the server operation idempotent.
- Persist long-form input locally so a session timeout is not a disaster.
- Validate in both places, ideally from one shared schema.
Terms in this lesson
Field notes
Loaded from a deliberately slow source. The lesson above was already readable while this was still travelling. That is streaming, and it is the same trick a chat interface uses.
The bug was three caches deep
A team spent two days on a "deploy that did not work". The deploy was fine. A CDN rule was caching the HTML document itself for an hour, so every visitor kept getting the previous build. The fix was one header; finding it needed knowing the copies existed.
Reported by a solo founder, 2024
Nobody had opened the empty state
A product launched with a dashboard that looked superb with demo data and completely blank on day one. Every new signup saw an empty white rectangle and assumed the app was broken. Signup-to-activation doubled after a two-hour fix.
Common enough to be a cliché
resolved in 900ms · region iad1
Hide field notes toggles a search param the loader reads. With it off, the slow promise is never created, so nothing streams.