How to know user has clicked X or the Close button?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
In a web page, you generally cannot know with certainty that the user specifically clicked the browser tab’s X button or chose “Close” from a menu. Browsers intentionally do not expose that distinction because it would leak too much control over browser UI and user behavior. What you can detect is that the page is about to be unloaded or hidden, and then decide whether to save state or warn about unsaved changes.
What Browsers Actually Let You Detect
The web platform exposes events around page lifecycle, not around browser chrome buttons.
The main ones are:
- '
beforeunload,' - '
pagehide,' - '
visibilitychange.'
These events can happen when the user:
- closes the tab,
- closes the window,
- refreshes,
- navigates away,
- switches tabs,
- moves the page into the back-forward cache path.
That is the key limitation: closing is only one possible cause.
Use beforeunload for Unsaved Changes
If the goal is “warn the user before leaving,” beforeunload is the standard tool.
Modern browsers ignore custom text in the dialog, but they may still show a generic confirmation message when the page has unsaved changes.
This event does not tell you “the user clicked X.” It tells you the document is about to unload.
Use pagehide or visibilitychange for Cleanup
If the goal is lightweight cleanup or telemetry, use pagehide or visibilitychange.
sendBeacon is useful because it is designed for fire-and-forget delivery during page shutdown.
What You Cannot Reliably Distinguish
From page JavaScript alone, you cannot reliably distinguish:
- close button versus refresh,
- close button versus typing another URL,
- close tab versus closing the whole browser window.
If an application absolutely needs durable save behavior, it should save continuously or on important state changes rather than waiting for a “close” event that may never be delivered in the exact way you expect.
Better Product Strategy: Save Early
For serious user data, the safest strategy is autosave.
This avoids depending on fragile unload timing and gives users a better experience than warning dialogs alone.
Browser Restrictions Are Intentional
Browsers restrict unload behavior because the web would be hostile if pages could:
- detect every browser UI action precisely,
- block closing arbitrarily,
- show custom persuasive messages on exit,
- run long asynchronous shutdown logic freely.
That is why unload-related APIs are limited, and why behavior differs somewhat between browsers and mobile platforms.
When the Requirement Is a Desktop App
If this is an Electron app or another desktop shell rather than a normal web page, the answer changes. Desktop runtimes often do expose actual window-close events. But in standard browser JavaScript, you should assume only page lifecycle signals, not browser button intent.
Common Pitfalls
- Expecting browser JavaScript to distinguish the X button from refresh or navigation with certainty.
- Relying on
beforeunloadas the only way to preserve important user data. - Showing unload warnings too aggressively and creating a poor user experience.
- Trying to send large asynchronous requests during page shutdown instead of using lightweight mechanisms such as
sendBeacon. - Confusing web-page lifecycle events with desktop window-management events from Electron or native apps.
Summary
- You cannot reliably detect that the user specifically clicked the browser’s close button in ordinary web JavaScript.
- You can detect page unload or hidden-state transitions with
beforeunload,pagehide, andvisibilitychange. - Use
beforeunloadonly for unsaved-change warnings, not as a general business workflow trigger. - Prefer autosave and lightweight cleanup over close-time logic.
- If you need true window-close detection, verify that you are in a desktop runtime rather than a standard browser page.

