]> git.ipfire.org Git - thirdparty/vuejs/router.git/commitdiff
fix(router): use pagehide for iOS navigation (#2537) main
authoromnomnom <boa@omnomnom.app>
Mon, 4 Aug 2025 06:55:03 +0000 (08:55 +0200)
committerGitHub <noreply@github.com>
Mon, 4 Aug 2025 06:55:03 +0000 (08:55 +0200)
Co-authored-by: omnomnom <contact@omnomnom.app>
Co-authored-by: Eduardo San Martin Morote <posva13@gmail.com>
packages/router/src/history/html5.ts

index 0f7a169a5c65d62c3868c009e0592e4c56172539..79c5cedf0e38182450f68e504815cd476c2759bb 100644 (file)
@@ -127,28 +127,31 @@ function useHistoryListeners(
   }
 
   function beforeUnloadListener() {
-    const { history } = window
-    if (!history.state) return
-    history.replaceState(
-      assign({}, history.state, { scroll: computeScrollPosition() }),
-      ''
-    )
+    if (document.visibilityState === 'hidden') {
+      const { history } = window
+      if (!history.state) return
+      history.replaceState(
+        assign({}, history.state, { scroll: computeScrollPosition() }),
+        ''
+      )
+    }
   }
 
   function destroy() {
     for (const teardown of teardowns) teardown()
     teardowns = []
     window.removeEventListener('popstate', popStateHandler)
-    window.removeEventListener('beforeunload', beforeUnloadListener)
+    window.removeEventListener('pagehide', beforeUnloadListener)
+    document.removeEventListener('visibilitychange', beforeUnloadListener)
   }
 
   // set up the listeners and prepare teardown callbacks
   window.addEventListener('popstate', popStateHandler)
-  // TODO: could we use 'pagehide' or 'visibilitychange' instead?
   // https://developer.chrome.com/blog/page-lifecycle-api/
-  window.addEventListener('beforeunload', beforeUnloadListener, {
-    passive: true,
-  })
+  // note: iOS safari does not fire beforeunload, so we
+  // use pagehide and visibilitychange instead
+  window.addEventListener('pagehide', beforeUnloadListener)
+  document.addEventListener('visibilitychange', beforeUnloadListener)
 
   return {
     pauseListeners,