From e0e38abd0ba1cabdaaf4616b59296701fe4942a0 Mon Sep 17 00:00:00 2001 From: omnomnom Date: Mon, 4 Aug 2025 08:55:03 +0200 Subject: [PATCH] fix(router): use pagehide for iOS navigation (#2537) Co-authored-by: omnomnom Co-authored-by: Eduardo San Martin Morote --- packages/router/src/history/html5.ts | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/packages/router/src/history/html5.ts b/packages/router/src/history/html5.ts index 0f7a169a..79c5cedf 100644 --- a/packages/router/src/history/html5.ts +++ b/packages/router/src/history/html5.ts @@ -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, -- 2.47.2