fix : page progress false progress and on canceling page change

This commit is contained in:
2026-09-17 18:40:47 +07:00 Unverified
parent 74497d280e
commit 1cfdc26404
+26 -5
View File
@@ -13,6 +13,8 @@ function PageProgressContent() {
// Start progress on click // Start progress on click
useEffect(() => { useEffect(() => {
const handleClick = (e: MouseEvent) => { const handleClick = (e: MouseEvent) => {
if (e.defaultPrevented) return
const target = (e.target as HTMLElement).closest("a") const target = (e.target as HTMLElement).closest("a")
if (!target) return if (!target) return
@@ -48,6 +50,30 @@ function PageProgressContent() {
return () => document.removeEventListener("click", handleClick) return () => document.removeEventListener("click", handleClick)
}, []) }, [])
// A canceled native beforeunload prompt leaves the current document alive.
// The timeout only gets a chance to run when the user chooses to stay.
useEffect(() => {
const handleBeforeUnload = () => {
const navigationUrl = navigationUrlRef.current
if (!navigationUrl) return
window.setTimeout(() => {
if (window.location.href !== navigationUrl) return
if (intervalRef.current) {
clearInterval(intervalRef.current)
intervalRef.current = null
}
navigationUrlRef.current = null
setIsVisible(false)
setProgress(0)
}, 0)
}
window.addEventListener("beforeunload", handleBeforeUnload)
return () => window.removeEventListener("beforeunload", handleBeforeUnload)
}, [])
// Detect completion without reading Next.js URL hooks during prerendering. // Detect completion without reading Next.js URL hooks during prerendering.
useEffect(() => { useEffect(() => {
if (!isVisible || !navigationUrlRef.current) return if (!isVisible || !navigationUrlRef.current) return
@@ -58,13 +84,8 @@ function PageProgressContent() {
setNavigationKey((key) => key + 1) setNavigationKey((key) => key + 1)
} }
}, 50) }, 50)
const fallback = window.setTimeout(() => {
window.clearInterval(checkInterval)
setNavigationKey((key) => key + 1)
}, 10_000)
return () => { return () => {
window.clearInterval(checkInterval) window.clearInterval(checkInterval)
window.clearTimeout(fallback)
} }
}, [isVisible]) }, [isVisible])