question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Browser Back Button does not trigger window.onbeforeunload

See original GitHub issue

In our application we have forms and want to prompt the user when they click the browser’s Back or Forward buttons to notify them they will lose their data if they continue.

  • I have searched the issues of this repository and believe that this is not a duplicate.

Although it is similar in nature to this issue that has been marked as Exploration

Expected Behavior

When user clicks back button, window.onbeforeunload function that is defined fires

Current Behavior

Browser redirects user to previous page without triggering window.onbeforeunload action

Special Notes

If I navigate directly to the page with the form by typing in the url, clicking the Back button correctly triggers window.onbeforeunload.

If I navigate away from the page with the form by typing in the url for another page, the window.onbeforeunload event fires correctly.

If I navigate to the page using links within the application, clicking the Back button does not trigger window.onbeforeunload.

I think this has something to do with they way the browser is treating our application when the user navigates within the application using Next Links. Instead of seeing each view as its own page and loading/unloading the page resources as the user navigates, it sees the entire application as just one page, thereby never loading/unloading resources and thus not triggering window.onbeforeunload.

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Reactions:14
  • Comments:33 (6 by maintainers)

github_iconTop GitHub Comments

35reactions
roderickhodgsoncommented, Nov 24, 2020

Thanks for that snippet @Fensterbank. Super useful.

I did notice one possible issue with it. Which I think is what prompted you to use the leaveConfirmed variable.

The function gets added as a listener to the event each time the component is rendered. So the page may end up creating hundreds of copies of that function, and calling each one of those copies when a user browses internally. And these never get cleared. Of course that might not be an issue in many use cases. But it was a problem with my particular scenario. Either way, I might suggest adding the router event listener in an event hook, just like the window beforeunload listener.

Here is a version with this approach, for anyone who gets to this page looking for another solution. Note, I have adapted it a bit further for my requirements.

  // prompt the user if they try and leave with unsaved changes
  useEffect(() => {
    const warningText =
      'You have unsaved changes - are you sure you wish to leave this page?';
    const handleWindowClose = (e: BeforeUnloadEvent) => {
      if (!unsavedChanges) return;
      e.preventDefault();
      return (e.returnValue = warningText);
    };
    const handleBrowseAway = () => {
      if (!unsavedChanges) return;
      if (window.confirm(warningText)) return;
      router.events.emit('routeChangeError');
      throw 'routeChange aborted.';
    };
    window.addEventListener('beforeunload', handleWindowClose);
    router.events.on('routeChangeStart', handleBrowseAway);
    return () => {
      window.removeEventListener('beforeunload', handleWindowClose);
      router.events.off('routeChangeStart', handleBrowseAway);
    };
  }, [unsavedChanges]);

So far, it seems to work pretty reliably.

13reactions
ahtashamabbassecommented, Sep 28, 2020

Following code work for me. 🚀

const handleWindowClose = (e) => {
    if (isDirty) {
      e.preventDefault();
      return e.returnValue = 'You have unsaved changes - are you sure you wish to close?';
    }

  };

  React.useEffect(() => {
    window.addEventListener('beforeunload', handleWindowClose);

    return () => {
      window.removeEventListener('beforeunload', handleWindowClose);
    };

  });

@Nitaaq Try this snippet that will work.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Help required on onbeforeunload or click on browser back ...
Note: Already I tried the onbeforeunload method, but it is working for all the navigation actions. For Example, clicking the link on the...
Read more >
Window: beforeunload event - Web APIs | MDN
This event enables a web page to trigger a confirmation dialog asking the user if they really want to leave the page. If...
Read more >
Solution to Browser Back Button Click Event Handling in ...
This article describes the onbeforeunload event as a possible solution for handling the browser back button click event.
Read more >
What event is fired when the back button of a browser ... - Quora
In JavaScript, onbeforeunload event is fired when the page is about to unload and there can be multiple reasons for this unload. Code...
Read more >
Sure you want to leave?—browser beforeunload event
window.addEventListener('beforeunload', (event) => ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found