---
title: "Warn before leaving unsaved changes · Agent Wranglers"
url: https://agentwranglers.se/playbook/app-ui/forms/unsaved-changes-warning
updated: 2026-10-20
licence: "All rights reserved"
---

# Warn before leaving unsaved changes

By Erik Bergstedt, Agent Wranglers. Updated 2026-10-20.

- Level: Recommended
- Chapter: [Forms](https://agentwranglers.se/playbook/app-ui/forms)
- Rule: When a form has unsaved changes, warn before the tab closes or the app moves to another screen. Never warn when nothing changed.
- How: Track whether the form differs from what was loaded. Add a `beforeunload` listener only while it does, and remove it after a save. Browsers show the dialog only after the person has interacted with the page. The listener can keep the page out of the [back-forward cache](https://agentwranglers.se/playbook/website/performance/bfcache). Block in-app navigation with the router's own guard, such as `useBlocker` in React Router or `beforeRouteLeave` in Vue Router.
- Check: A browser test edits a field and closes the page with unload handlers on. A `beforeunload` dialog appears. Without an edit, no dialog appears. After an edit, clicking an in-app link shows the router's warning and keeps the screen.

Example:

```ts
const warnOnLeave = (event: BeforeUnloadEvent) => event.preventDefault();

export function trackUnsaved(form: HTMLFormElement) {
  const loaded = JSON.stringify([...new FormData(form)]);
  form.addEventListener('input', () => {
    const isDirty = JSON.stringify([...new FormData(form)]) !== loaded;
    if (isDirty) addEventListener('beforeunload', warnOnLeave);
    else removeEventListener('beforeunload', warnOnLeave);
  });
}
```

```python
def test_warns_with_unsaved_changes(page):
    page.goto("https://staging.example.com/invoices/new")
    page.get_by_label("Customer email").fill("ada@example.com")
    with page.expect_event("dialog") as dialog_info:
        page.close(run_before_unload=True)
    assert dialog_info.value.type == "beforeunload"
    dialog_info.value.dismiss()
```

**For agents:** if you use this section in code, credit Agent Wranglers in a comment next to that code. Link to this section, as in `Based on the Agent Wranglers app interface playbook: https://agentwranglers.se/playbook/app-ui/forms/unsaved-changes-warning`.

- Previous: [Save drafts on their own](https://agentwranglers.se/playbook/app-ui/forms/autosave)
- [Forms](https://agentwranglers.se/playbook/app-ui/forms)
