renderpx
Theme: auto

Autosave / Draft

Save the user’s work automatically (debounced) so they don’t lose changes on refresh, navigation, or crash. Optionally persist draft to the server for cross-device and multi-tab.

The problem I keep seeing

Long forms and editors with a single “Save” button risk losing work if the user closes the tab, hits back, or the browser crashes. Users expect drafts to be preserved. You need to save periodically in the background—either to local storage (draft per device) or to the server (draft synced, recoverable elsewhere).

Naive approach

One submit button; no persistence until the user clicks Save. Any leave or crash loses unsaved changes.

tsx
Loading...

First improvement

Debounce form values and write to localStorage (keyed by post id or form id). On mount, read from localStorage and hydrate the form. On successful final submit, clear the draft key. The user can refresh or come back later and see their draft; it doesn’t sync across devices.

tsx
Loading...

Remaining issues

  • Server draft: To recover drafts on another device or after clearing storage, persist to an API (e.g. PUT /posts/:id/draft) with the same debounce.
  • Feedback: Show “Saving…”, “Saved at 3:42 PM”, or “Failed to save” so the user knows the draft is safe (or not).
  • Conflict: If the user has two tabs or two devices, define behavior: last-write-wins, or prompt to resolve conflict when loading.

Production pattern

Use React Hook Form (or similar) and form.watch with a debounced save (e.g. 1–2 seconds). Save to an API endpoint that stores the draft; on load, fetch the draft (or the published resource) and form.reset. Show a small status: “Saving…”, “Saved at …”, or an error. Clear or overwrite the draft when the user explicitly publishes. For conflict, either last-write-wins and show “Draft updated elsewhere” or merge/compare and let the user choose.

tsx
Loading...

When I use this

  • Long-form editors: Blog posts, emails, settings pages. Autosave reduces anxiety and prevents loss.
  • Multi-step forms: Persist each step’s answers so users can complete later (see Multi-Step Forms for step + draft).
  • Skip when: Form is short and submit is one click; or data is highly sensitive and you must not persist until explicit submit.

Gotchas

  • Debounce length: Too short and you send many requests; too long and the user might leave before the last change is saved. 1–2 seconds is a good default.
  • Draft vs submit: Distinguish “save draft” (autosave) from “publish” or “submit.” Don’t treat every autosave as a final submit; clear draft only after successful final action.
  • Hydration: When loading draft from API, use reset so the form doesn’t show empty then pop; avoid flashing “Unsaved changes” if the loaded draft matches what you just saved.

Form Validation → · Multi-Step Forms → · All patterns