1

Im trying to prompt user before leaving page. I Noticed when user enters page from a element link then when I click back, beforeunload event fires.

However, when user enters page through NextJs Link component then clicking back wont fire beforeunload event.

How can I still prompt user when using component?

for example going tho page through this Link and clicking back wont trigger beforeunload

<Link href={`/event/${encodeURIComponent(event.slug)}`}>
      <a>
        <h3>{event.name}</h3>
      </a>
</Link>

but regular a element linking will then afterwards fire beforeunload when clicking back

example

<a href={"event/" + event.slug}>
      <h3>{event.name}</h3>
</a>
Jeekim
  • 543
  • 5
  • 15
  • Would a solution like [Want to have an event handler for the browser's back button with next.js](https://stackoverflow.com/a/69569682/1870780) work for your use-case? It uses `next/router`'s [`beforePopState`](https://nextjs.org/docs/api-reference/next/router#routerbeforepopstate) to listen for route changes. – juliomalves Oct 26 '21 at 12:26

2 Answers2

1

According to the Next.js documentation, when you are using the Link component:

Client-side transitions between routes can be enabled via the Link component exported by next/link. The Next.js router allows you to do client-side route transitions between pages, similar to a single-page application.

You are using the Link component to change your routes, so it's considered you are on a single page (even go back and forward many times).

Now, take a look at Window: beforeunload event on MDN:

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

So, as you use the Link component with mentioned specific, it't a proper behavior.

As a solution to solve the issues, you can add useEffect hook and do the proper action on it or on the cleanup method. for example, put your function in the useEffect on the desired page to get called on component did mount. in this way, with every change on the routes or pages, the useEffect will be triggered.

nima
  • 7,796
  • 12
  • 36
  • 53
0

updated solution 2023

This is a solution for the pages directory (not tested on app!). It detects whenever you switch a page or leave the page in Next.js

How it works:

  1. Uses router change events - to track when changing page without refresh
  2. Uses window.onbeforeunload event - to track when user closed the tab or refreshed the page

Code:

Please use this code in the _app.js file. You can also put it in a specific page but then it won't execute on all the pages. You can also make a seperate file for this and import it wherever needed.

  useEffect(() => {
    const exitingFunction = async () => {
      console.log("exiting...");
    };

    router.events.on("routeChangeStart", exitingFunction);
    window.onbeforeunload = exitingFunction;

    return () => {
      console.log("unmounting component...");
      router.events.off("routeChangeStart", exitingFunction);
    };
  }, []);
Coder Gautam YT
  • 1,044
  • 7
  • 20