Unsubmitted input drafts should survive leaving by navigation, not be cleared
Aliases: keep draft on navigate · unsaved draft · in-session draft
What it is
A comment is half-written. The person checks a source, opens an image, switches to another thread, and comes back. The unsent words should still be there. Keeping a draft across casual navigation is about a short walk away in the same session, not a multi-day long-flow archive, and not crash recovery. Clearing happens in the instant the router unmounts the input and remounts it with initial state—while the person thought they were only glancing elsewhere.
Why it happens
Draft text lives in a component instance. An SPA implements “leave” as unmount; the instance dies, the value dies. Browsers keep ordinary form fields on a bfcache hit, but many sites disable that cache, or fake an input with a contenteditable div, so return is empty. People treat navigation as a temporary shift of attention; the sentence is still in working memory. An empty box upgrades the shift into a loss. The loss is silent: no submit failure, no error, only words gone, noticed when they try to continue.
The grain of same-session keep is “unsubmitted input on this object”: this comment, this ticket description, this unsent rewrite in a search box. It is not the same object as account-side application progress—it may die when the tab dies; it should preferably survive refresh. Calling reset() on every route change announces that “looking elsewhere = abandoning this sentence.”
Studying it
Type a sentence that cannot be copied from elsewhere into an input. Navigate to another in-site page and return (or open a modal and close it). Compare keep-alive, a session-level draft, and clear-on-unmount.
- Dependent variables: whether the text is verbatim on return, time to notice loss, whether it is retyped.
- Independent variables: how they left (route / modal / new tab), storage (memory only / sessionStorage / none).
- Methodological note: if the brief says “please remember what you typed,” people copy first and the test measures memory, not drafts. Make them walk away while they still intend to continue writing. Do not mix “tapped Cancel” with “tapped a link elsewhere”—cancel is discard, navigation is not. Long-flow archive studies measure a cross-session cursor; this leaf only measures a same-session round-trip.
Where it stops holding
After “Clear,” “Cancel,” or a successful send, the draft should vanish. Passwords, one-time codes, and payment factors must not enter a recoverable layer even in-session. Input on a public screen should die on leave so the next glance cannot be shoulder-surfed. The same form in a new tab is another instance; default sync would race two writers unless the product is explicitly collaborative editing.
Applying it
- For meaningful unsubmitted input, write a session-level store keyed by object id before unmount; read it back when that object remounts, instead of the initial empty value.
- List → detail → list: if the comment box still faces the same object, it must read back.
- Delete the key on successful send or explicit cancel.
- Verify: write half a comment, open an image or another detail, return. The half sentence is there. Refresh the same page: preferably still there. Switch to another object and back: someone else’s draft must not leak. As a counter-example,
setState('')on unmount; the same actions drop the words.
Related
- Within the group: G4.07.1 When a list mutates while away, restore the item, not the pixel offset · G4.07.2 Infinite-scroll restore depends on how much was loaded; returning too deep retriggers fetch · G4.07.4 When position restore fails, say why—deleted or reordered · G4.07.5 Cross-device resume stores position on the account, not in local state
- Adjacent: G4.05 Resume from interruption · H1.08 Draft autosave · G4.08 External links and leave warnings
- Search terms:
unsaved draft·in-session persistence·comment draft
Cards in the same group
- G4.07.1When a list mutates while away, restore the item, not the pixel offset
- G4.07.2Infinite-scroll restore depends on how much was loaded; returning too deep retriggers fetch
- G4.07.4When position restore fails, say why—deleted or reordered
- G4.07.5Cross-device resume stores position on the account, not in local state