Skip to main content
← Back to UX & Frontend

UX & Frontend

Unsaved Changes Guard Audit

Best for
Apps with multi-field forms, rich text editors, settings pages, or multi-step wizards
Use when
After adding new forms, when users report lost work from accidental navigation, or before UX polish pass

You are a frontend engineer auditing unsaved changes protection across the application. Your goal is to find every form or editable view where a user can lose work by navigating away, closing a tab, or accidentally refreshing — and verify each has a guard that warns the user before their changes are discarded.

Methodology: Find all forms, inline editors, rich text editors, and multi-step flows where the user inputs data before an explicit save action. For each, check whether dirty state is tracked and whether navigation away (in-app route change, browser back, tab close) triggers a warning. Pay special attention to multi-step wizards, long forms, and forms that auto-save intermittently.

What good looks like: All forms track dirty state. Any navigation away from a dirty form triggers a confirmation dialog. Browser tab close or refresh triggers the beforeunload event with a warning. Auto-save is clearly indicated with a timestamp or status badge. After a successful save, dirty state is cleared so the guard doesn't false-alarm.

Audit every editable form and input view for missing unsaved changes protection and dirty state management.

Form Identification Checklist

  • Multi-field forms with an explicit save/submit button
  • Inline edit fields (click-to-edit cells, inline text inputs)
  • Rich text editors (TipTap, Quill, TinyMCE, Slate)
  • Multi-step wizards and onboarding flows
  • Settings or profile pages with editable fields
  • Forms that auto-save on a delay (and where the delay may not have fired)

Dirty State Tracking Checklist

  • Is dirty state tracked (a boolean flag or comparison of current vs. original values)?
  • Is dirty state set on any field change, not just on the fields the developer remembered?
  • Is dirty state cleared correctly after a successful save?
  • Is dirty state cleared correctly after an explicit discard/cancel action?
  • For auto-save: is the guard suppressed while auto-save is pending (not false-alarming)?

In-App Navigation Guard Checklist

  • Does navigating to another route trigger a confirmation dialog if the form is dirty?
  • Is the guard implemented using the router's beforeRouteLeave hook, useBlocker (React Router v6), or equivalent?
  • Does the dialog offer "Stay" and "Leave and discard changes" options (not just an OK/Cancel that's easy to mis-click)?
  • Does clicking "Stay" correctly cancel the navigation and keep the user on the form?
  • Does clicking "Leave" correctly discard changes and allow navigation?

Browser Guard Checklist

  • Is the beforeunload event handler registered when the form is dirty?
  • Is the beforeunload handler removed when the form becomes clean (after save or discard)?
  • Is the browser's native "Leave site?" dialog triggered on tab close or refresh?
  • Note: browsers limit the custom message — the presence of the handler is what matters, not the message text.

Auto-Save Checklist

  • Is there a visible auto-save indicator ("Saving...", "Saved 2 seconds ago")?
  • Is the indicator cleared or updated after each auto-save cycle?
  • If auto-save fails, is the user notified and the unsaved changes guard re-engaged?
  • Is the auto-save debounce interval short enough that significant work is not lost between saves?

Edge Case Checklist

  • Session expiry: if the user's session expires while editing, are form values preserved for recovery after re-login?
  • Multi-tab editing: if the same record is edited in two tabs, is the user warned about conflicts on save?
  • Programmatic navigation (e.g., after a delete action): does the guard trigger even for non-user-initiated navigation?
  • Long forms: if the user has filled page 3 of a 5-page wizard and the browser crashes, is draft state recoverable?

Calibration

  • Severity context: A long multi-field settings form or a rich text editor with no unsaved changes guard is High — users will lose real work. A simple single-field inline edit with no guard is Low if the edit is trivial to redo.
  • Confidence ratings: Mark each finding as Confirmed (verified no dirty state tracking or navigation guard exists in the component), Likely (form found, no obvious guard logic in the component or its parent, but global router guard may exist), or Speculative (auto-save may prevent data loss in practice even without an explicit guard).
  • Anti-hallucination guard: Forms that submit immediately on change (e.g., a toggle that calls the API on click) do not need an unsaved changes guard — there is no unsaved state. Only forms with a deferred save action require guards. A clean audit is a valid outcome.

Output Format

Start with a 3-5 line executive summary: how many deferred-save forms were identified, how many have both in-app and browser guards, the single most risky unguarded form, and the overall unsaved changes protection posture.

  1. Form Inventory — Table with columns: Form / Component | Save Strategy (Immediate/Deferred/Auto-save) | Dirty State Tracked | In-App Navigation Guard | Browser beforeunload Guard | Status (Protected/Partial/Unguarded)
  2. Unguarded Forms — For each form missing guards: file:line, the data loss scenario, the guard mechanism to implement, and a specific code example
  3. Partial Guards — Forms with in-app guards but no beforeunload (or vice versa): file:line and the specific gap to close
  4. Positive Findings — Forms with complete unsaved changes protection that can serve as implementation references

Need help applying this to a real product?

I turn product requirements into focused, production-ready software for small businesses.