-2

I hope you are doing well!

I am trying to catch the window close or tab close or refresh event in my project and I tried all possible solutions but haven't succeeded.

I tried using:

  useEffect(() => {
    return () => {
      window.alert("Alert");
    };
  });

and I tried:

  useEffect(() => {
    window.onbeforeunload = () => {
      window.alert("alert");
    };
    return () => {
      window.onbeforeunload = null;
    };
  });

which seems to only trigger if I have my window in the background for a while.

and I tried:

  window.addEventListener("onbeforeunload", () => {
    window.alert("alert");
  });

but haven't been able to capture it.

I will use this functionality to send data to a specific API whenever the user closes the window or tab or refreshes (and possibly turns off the PC while on the page if that is event possible). But all these methods weren't working for me.

Is there any other way or is there a reason they aren't working?

Thank you for your time!

2 Answers2

1

You might need to call preventDefault, and I think the event is called beforeunload, try:

window.addEventListener("beforeunload", ev => {
  ev.preventDefault()
  return (ev.returnValue = "Are you sure you want to close?")
})

When registering event listeners, you should do this with useEffect so you properly remove the listeners.

useEffect(() => {
  const onUnload = (e: any) => {
    e.preventDefault()
    return (e.returnValue = "Are you sure you want to close?")
  }
  
  window.addEventListener("beforeunload", onUnload)

  return () => window.removeEventListener("beforeunload", onUnload)
}, [])

Some things to know about beforeunload:

It does not call blocking functions such as alert, prompt or confirm. It is evident from a user perspective.

And it is fired only if there has been ANY user interaction with the site. Without ANY interaction (even one click anywhere) event beforeunload won't be fired.

Fralle
  • 889
  • 6
  • 12
  • This is only working when I want to refresh my window, but on tab close or window close it isn't going off – Selim Choueiter Nov 03 '22 at 09:26
  • I have updated my answer with some information at the bottom. Maybe that clarifies why it isn't working for you. – Fralle Nov 03 '22 at 09:33
  • You are correct, I tried it with an API call instead of ```window.alert``` and it did call the function. But can I stop the action? Like if I want to display a custom prompt that changes need to be saved? – Selim Choueiter Nov 03 '22 at 09:55
  • If you do a preventDefault and setting returnValue, it should stop the user from exiting the site IF they have interacted with it beforehand. – Fralle Nov 03 '22 at 09:58
0

It is impossible to catch a tab/browser close and even if it was, it was not going to be reliable as the user might force close the browser or kill the process, etc.

So the best option I found, I wrapped in a NPM package here: https://www.npmjs.com/package/@garage-panda/use-before-unload

Take a look and let me know if it works for you.

This is how you use it:

const setEnabledBeforeUnload = useBeforeUnload({
  initEnable: false, // do you need to be enabled by default
  onRefresh: () => {
    // the page has been refreshed (the user has clicked Reload)
  },
  onCancel: () => {
    // the user has clicked Cancel
  }
});

And the only possible (and the correct way) to know if the user has left your page is to actually catch the event when he lands on your page (e.g. the sessionStorage is empty).

Vladimir Vladimirov
  • 269
  • 1
  • 2
  • 14