Window: beforeunload event

Limited availability

This feature is not Baseline because it does not work in some of the most widely-used browsers.

The beforeunload event is fired when the current window, contained document, and associated resources are about to be unloaded. The document is still visible and the event is still cancelable at this point.

The main use case for this event is to trigger a browser-generated confirmation dialog that asks users to confirm if they really want to leave the page when they try to close or reload it, or navigate somewhere else. This is intended to help prevent loss of unsaved data.

The dialog can be triggered in the following ways:

  • Calling the event object's preventDefault() method.
  • Setting the event object's returnValue property to a non-empty string value or any other truthy value.
  • Returning any truthy value from the event handler function, e.g., return "string". Note that this only works when the function is attached via the onbeforeunload property, not the addEventListener() method. This behavior is consistent across modern versions of Firefox, Safari, and Chrome.

The last two mechanisms are legacy features; best practice is to trigger the dialog by invoking preventDefault() on the event object, while also setting returnValue to support legacy cases.

Syntax

Use the event name in methods like addEventListener(), or set an event handler property.

js
addEventListener("beforeunload", (event) => { })

onbeforeunload = (event) => { }

Event type

A BeforeUnloadEvent. Inherits from Event.

Usage notes

To trigger the dialog being shown when the user closes or navigates the tab, a beforeunload event handler function should call preventDefault() on the event object. You should note that modern implementations:

  • Require sticky activation for the dialog to be displayed. In other words, the browser will only show the dialog box if the frame or any embedded frame receives a user gesture or user interaction. If the user has never interacted with the page, then there is no user data to save, so no legitimate use case for the dialog.
  • Only show a generic browser-specified string in the displayed dialog. This cannot be controlled by the webpage code.

The beforeunload event suffers from some problems:

  • It is not reliably fired, especially on mobile platforms. For example, the beforeunload event is not fired at all in the following scenario:

    1. A mobile user visits your page.
    2. The user then switches to a different app.
    3. Later, the user closes the browser from the app manager.

    Note: It is recommended to use the visibilitychange event as a more reliable signal for automatic app state saving that gets around problems like the above. See Don't lose user and app state, use Page Visibility for more details.

  • In Firefox, beforeunload is not compatible with the back/forward cache (bfcache): that is, Firefox will not place pages in the bfcache if they have beforeunload listeners, and this is bad for performance.

It is therefore recommended that developers listen for beforeunload only when users have unsaved changes so that the dialog mentioned above can be used to warn them about impending data loss, and remove the listener again when it is not needed. Listening for beforeunload sparingly can minimize the effect on performance.

Event handler aliases

In addition to the Window interface, the event handler property onbeforeunload is also available on the following targets:

Examples

In the following example we have an HTML text <input> to represent some data that could be changed and require saving:

html
<form>
  <input type="text" name="name" id="name" />
</form>

Our JavaScript attaches an input event listener to the <input> element that listens for changes in the inputted value. When the value is updated to a non-empty value, a beforeunload event listener is attached to the Window object.

If the value becomes an empty string again (i.e., the value is deleted), the beforeunload event listener is removed again — as mentioned above in the Usage notes, the listener should be removed when there is no unsaved data to warn about.

The beforeunload event handler function invokes event.preventDefault() to trigger the warning dialog when the user closes or navigates the tab. We have also included event.returnValue = true in the handler function so that any browsers that don't support the event.preventDefault() mechanism will still run the demo correctly.

js
const beforeUnloadHandler = (event) => {
  // Recommended
  event.preventDefault();

  // Included for legacy support, e.g. Chrome/Edge < 119
  event.returnValue = true;
};

const nameInput = document.querySelector("#name");

nameInput.addEventListener("input", (event) => {
  if (event.target.value !== "") {
    window.addEventListener("beforeunload", beforeUnloadHandler);
  } else {
    window.removeEventListener("beforeunload", beforeUnloadHandler);
  }
});

When the <input> value is non-empty, if you try to close, navigate, or reload the page the browser displays the warning dialog. Try it out:

Specifications

Specification
HTML
# event-beforeunload
HTML
# handler-window-onbeforeunload

Browser compatibility

desktop mobile server
Chrome
Edge
Firefox
Opera
Safari
Chrome Android
Firefox for Android
Opera Android
Safari on iOS
Samsung Internet
WebView Android
WebView on iOS
Deno
beforeunload event
Chrome – Full support
Chrome 1 (Release date: 2008-12-11)
footnote Full support
Edge – Full support
Edge 12 (Release date: 2015-07-29)
footnote Full support
Firefox – Full support
Firefox 1 (Release date: 2004-11-09)
footnote Full support
Opera – Full support
Opera 12 (Release date: 2012-06-14)
footnote Full support
Safari – Full support
Safari 3 (Release date: 2007-10-26)
footnote Full support
Chrome Android – Full support
Chrome Android 18 (Release date: 2012-06-27)
footnote Full support
Firefox for Android – Full support
Firefox for Android 4 (Release date: 2011-03-29)
footnote Full support
Opera Android – Full support
Opera Android 12 (Release date: 2012-02-25)
footnote Full support
Safari on iOS – No support
Safari on iOS
footnote
footnote See bug 219102
Samsung Internet – Full support
Samsung Internet 1 (Release date: 2013-04-27)
footnote Full support
WebView Android – Full support
WebView Android 4.4 (Release date: 2013-12-09)
footnote Full support
WebView on iOS – No support
WebView on iOS
footnote
footnote See bug 219102
Deno – Full support
Deno 1.27 (Release date: 2022-10-27)
footnote Full support
Activation by setting event.returnValue to any truthy value
Deprecated
Chrome – Partial support
Chrome 30 – 118 (Release date: 2013-10-01)
footnote Partial support
footnote Before Chrome 119, an empty string incorrectly activated the confirmation dialog.
Chrome – Full support
Chrome 119 (Release date: 2023-10-31)
footnote Full support
Edge – Partial support
Edge 79 – 118 (Release date: 2020-01-15)
footnote Partial support
footnote Before Edge 119, an empty string incorrectly activated the confirmation dialog.
Edge – Full support
Edge 119 (Release date: 2023-11-02)
footnote Full support
Firefox – Full support
Firefox 6 (Release date: 2011-08-16)
footnote Full support
Opera – Partial support
Opera 17 – 104 (Release date: 2013-10-08)
footnote Partial support
footnote Before Opera 105, an empty string incorrectly activated the confirmation dialog.
Opera – Full support
Opera 105 (Release date: 2023-11-14)
footnote Full support
Safari – Full support
Safari 8 (Release date: 2014-10-16)
footnote Full support
Chrome Android – Partial support
Chrome Android 30 – 118 (Release date: 2013-10-02)
footnote Partial support
footnote Before Chrome Android 119, an empty string incorrectly activated the confirmation dialog.
Chrome Android – Full support
Chrome Android 119 (Release date: 2023-10-31)
footnote Full support
Firefox for Android – Full support
Firefox for Android 6 (Release date: 2011-08-16)
footnote Full support
Opera Android – Partial support
Opera Android 18 – 78 (Release date: 2013-11-20)
footnote Partial support
footnote Before Opera Android 79, an empty string incorrectly activated the confirmation dialog.
Opera Android – Full support
Opera Android 79 (Release date: 2023-12-06)
footnote Full support
Safari on iOS – No support
Safari on iOS
footnote No support
Samsung Internet – Partial support
Samsung Internet 2 – 24 (Release date: 2014-10-17)
footnote Partial support
footnote Before Samsung Internet 25.0, an empty string incorrectly activated the confirmation dialog.
Samsung Internet – Full support
Samsung Internet 25 (Release date: 2024-04-24)
footnote Full support
WebView Android – Partial support
WebView Android 4.4 – 118 (Release date: 2013-12-09)
footnote Partial support
footnote Before WebView Android 119, an empty string incorrectly activated the confirmation dialog.
WebView Android – Full support
WebView Android 119 (Release date: 2023-10-31)
footnote Full support
WebView on iOS – No support
WebView on iOS
footnote No support
Deno – No support
Deno
footnote No support
Dialog displays a generic string, not event handler return value
Deprecated
Chrome – Full support
Chrome 51 (Release date: 2016-05-25)
footnote Full support
Edge – Full support
Edge 12 (Release date: 2015-07-29)
footnote Full support
Firefox – Full support
Firefox 44 (Release date: 2016-01-26)
footnote Full support
Opera – Full support
Opera 38 (Release date: 2016-06-08)
footnote Full support
Safari – Full support
Safari 9.1 (Release date: 2016-03-21)
footnote Full support
Chrome Android – Full support
Chrome Android 51 (Release date: 2016-06-08)
footnote Full support
Firefox for Android – Full support
Firefox for Android 44 (Release date: 2016-01-26)
footnote Full support
Opera Android – Full support
Opera Android 41 (Release date: 2016-10-25)
footnote Full support
Safari on iOS – No support
Safari on iOS
footnote No support
Samsung Internet – Full support
Samsung Internet 5 (Release date: 2016-12-15)
footnote Full support
WebView Android – Full support
WebView Android 51 (Release date: 2016-06-08)
footnote Full support
WebView on iOS – No support
WebView on iOS
footnote No support
Deno – No support
Deno
footnote No support
Activation using event.preventDefault()
Chrome – Full support
Chrome 119 (Release date: 2023-10-31)
footnote Full support
Edge – No support
Edge 12 – 18 (Release date: 2015-07-29)
footnote Removed in 79 and later
Edge – Full support
Edge 119 (Release date: 2023-11-02)
footnote Full support
Firefox – Full support
Firefox 6 (Release date: 2011-08-16)
footnote Full support
Opera – Full support
Opera 105 (Release date: 2023-11-14)
footnote Full support
Safari – Full support
Safari 11 (Release date: 2017-09-19)
footnote Full support
Chrome Android – Full support
Chrome Android 119 (Release date: 2023-10-31)
footnote Full support
Firefox for Android – Full support
Firefox for Android 6 (Release date: 2011-08-16)
footnote Full support
Opera Android – Full support
Opera Android 79 (Release date: 2023-12-06)
footnote Full support
Safari on iOS – No support
Safari on iOS
footnote No support
Samsung Internet – Full support
Samsung Internet 25 (Release date: 2024-04-24)
footnote Full support
WebView Android – Full support
WebView Android 119 (Release date: 2023-10-31)
footnote Full support
WebView on iOS – No support
WebView on iOS
footnote No support
Deno – No support
Deno
footnote No support
Activation by returning a string
Deprecated
Chrome – Full support
Chrome 1 (Release date: 2008-12-11)
footnote Full support
Edge – Full support
Edge 12 (Release date: 2015-07-29)
footnote Full support
Firefox – Full support
Firefox 1 (Release date: 2004-11-09)
footnote Full support
Opera – Full support
Opera 12 (Release date: 2012-06-14)
footnote Full support
Safari – Full support
Safari 3 (Release date: 2007-10-26)
footnote Full support
Chrome Android – Full support
Chrome Android 18 (Release date: 2012-06-27)
footnote Full support
Firefox for Android – Full support
Firefox for Android 4 (Release date: 2011-03-29)
footnote Full support
Opera Android – Full support
Opera Android 12 (Release date: 2012-02-25)
footnote Full support
Safari on iOS – No support
Safari on iOS
footnote No support
Samsung Internet – Full support
Samsung Internet 1 (Release date: 2013-04-27)
footnote Full support
WebView Android – Full support
WebView Android 4.4 (Release date: 2013-12-09)
footnote Full support
WebView on iOS – No support
WebView on iOS
footnote No support
Deno – No support
Deno
footnote No support

Legend

Tip: you can click/tap on a cell for more information.

Full support
Full support
Partial support
Partial support
No support
No support
Deprecated. Not for use in new websites.
See implementation notes.
Has more compatibility info.

See also