beforeunload Event: Confirm Before Leaving a Page

To ask users to confirm before they close, reload or leave a page, add a beforeunload listener and call preventDefault(). The browser then shows its own confirmation dialog. You cannot change its text, and it only appears if the user has interacted with the page.
window.addEventListener('beforeunload', (event) => {
event.preventDefault();
event.returnValue = ''; // required by some older browsers
});
This is useful to stop people from losing unsaved changes, for example in a form or an editor.

How the beforeunload event works
The beforeunload event fires on window just before the page is unloaded: when the user closes the tab, reloads, types a new address or clicks a link to another site. If a listener calls event.preventDefault(), the browser asks the user to confirm. Pressing “Leave” continues, “Stay” cancels the navigation. See the MDN reference for beforeunload for the full details.
Using the onbeforeunload property in HTML
You can also use the onbeforeunload property instead of addEventListener:
<body onbeforeunload="return myFunction()">
<h1>The beforeunload Event</h1>
<p>Reload this page, or click on the link below to invoke the onbeforeunload event.</p>
<a href="/">Click here to go to codingislove.com</a>
<script>
function myFunction() {
event.preventDefault();
return "";
}
</script>
</body>
Demo
Here’s a live demo below
Why you can’t customize the message
If you set a custom string and it does not show up, that is expected. Modern browsers ignore the text and show a generic message instead. Chrome stopped showing custom strings in version 51 because the feature was being misused to scare or trick users. Firefox and Safari behave the same way. The dialog’s wording and look differ between browsers and versions.
The dialog only shows after user interaction
To prevent abuse, browsers show the dialog only if the user has interacted with the page, such as clicking or typing in it. If someone opens your page and closes it without touching anything, no dialog appears. Test by clicking into a form field first.
Remove the listener after saving
Only block navigation while there is something to lose. Add the listener when the form becomes dirty and remove it after a save, using the same function reference:
function handleBeforeUnload(event) {
event.preventDefault();
event.returnValue = '';
}
// user edits the form
window.addEventListener('beforeunload', handleBeforeUnload);
// after a successful save
window.removeEventListener('beforeunload', handleBeforeUnload);
React example with useEffect
In React, register the listener in an effect and clean it up when the state changes or the component unmounts:
import { useEffect } from 'react';
function useUnsavedChangesWarning(hasUnsavedChanges) {
useEffect(() => {
if (!hasUnsavedChanges) return;
const handler = (event) => {
event.preventDefault();
event.returnValue = '';
};
window.addEventListener('beforeunload', handler);
return () => window.removeEventListener('beforeunload', handler);
}, [hasUnsavedChanges]);
}
Call useUnsavedChangesWarning(isDirty) in your form component. This covers closing the tab and reloading. Navigation inside a single-page app (clicking a router link) does not fire beforeunload, so use your router’s own blocking feature for that.
Practical tips
- Use it only for real unsaved data, never as a retention trick.
- Keep the handler fast and do not run async work in it.
- Don’t rely on it for saving data or analytics: it may not fire on mobile when the app is backgrounded. Use the
visibilitychangeevent withnavigator.sendBeacon()for that. - It can affect the browser’s back/forward cache, so add it only while needed.
Conclusion
The beforeunload event is a simple way to confirm before leaving a page: call preventDefault(), accept that the message is the browser’s, and remove the listener once the data is saved. For more small JavaScript tricks, see our other quick tips for developers. Happy coding ✌️