Using "beforeunload" with live redirects

Hello everyone,

I’m currently working on a page that features a live view, and I’m aiming to prevent users from accidentally leaving the page. To achieve this, I’m utilizing the beforeunload browser event in conjunction with a Phoenix hook. The structure of the hook is as follows:

export default function preventPageLeave() {
  const beforeUnloadListener = (event) => {
    // Prevent navigation and display a confirmation dialog
    event.preventDefault();
    event.returnValue = '';
  };

  return {
    mounted() {
      window.addEventListener("beforeunload", beforeUnloadListener, { capture: true });
    }
  };
}

This approach works seamlessly; however, I’m encountering a challenge when dealing with links on the page that use the link/1 function. For redirects managed by the Phoenix socket, which don’t necessitate a full page reload like navigation or patch operations, the beforeunload technique doesn’t prove effective.

Regrettably, I haven’t yet found an elegant solution to address this particular issue. I would greatly appreciate any insights or suggestions you might have.

Thank you in advance for your assistance!

2 Likes

Maybe you could assign a class to link and then add event listener to all classes on the page?

Thanks for the reply, yes I tried this approach already something like this

On mount, I could do

      const links = document.querySelectorAll("a")
      for (var i = 0, len = links.length; i < len; i++) {
        links[i].addEventListener("click", triggerBeforeUnload);
      }

This works but I believe it is not the best idea, for example the live view might add new links to the dom on a certain user interaction which would not have the event listener and would therefore fail to intercept the event.

I feel like this is a common use case and there should be a elegant way to handle it.

Another option is If you are changing URL then you can listen for hashchange_event or popstate_event
Another option is MutationObserver

Following up on this topic – has there been any development on this?

I’m also using beforeunload to help my users avoid shooting themselves in the foot. The live navigation part is still blindspot.

@arpan, did you have any success with @regex.sh 's suggested approaches?


I hope that many would appreciate the bump of this thread if it’s possible to increase the ergonomics in this regard :slight_smile:

This is the hook that I use right now

export default function prevent_page_leave() {
  const beforeUnloadListener = (event) => {
    // Prevent navigation and show confirmation dialog
    event.preventDefault();
    return event.returnValue = '';
  };

  return {
    mounted() {
      window.addEventListener("beforeunload", beforeUnloadListener, { capture: true });

      // Remove "beforeunload" event listener and redirect to given path
      addEventListener(
        "phx:force_redirect",
        e => {
          window.removeEventListener("beforeunload", beforeUnloadListener, { capture: true });
          window.location.href = e.detail.to;
        }
      )
    }
  };
}