Skip to content

Commit 35b29e6

Browse files
committed
fix(landing-nav): hoist popstate flag to module scope and skip on hash anchors
1 parent 2911924 commit 35b29e6

1 file changed

Lines changed: 22 additions & 14 deletions

File tree

apps/sim/app/(landing)/components/scroll-to-top.tsx

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,41 @@
11
'use client'
22

3-
import { useEffect, useRef } from 'react'
3+
import { useEffect } from 'react'
44
import { usePathname } from 'next/navigation'
55

6+
/**
7+
* Module-level flag so the popstate signal survives layout remounts when the
8+
* user navigates across sections (e.g., blog ↔ integrations ↔ models), where
9+
* the outgoing layout — and its component instances — unmount before the
10+
* incoming layout's effect runs.
11+
*/
12+
let isPopNavigation = false
13+
14+
if (typeof window !== 'undefined') {
15+
window.addEventListener('popstate', () => {
16+
isPopNavigation = true
17+
})
18+
}
19+
620
/**
721
* Resets window scroll to the top on App Router pathname changes.
822
*
923
* Next.js's default scroll handling only brings the new Page element into view,
1024
* which often resolves to "no scroll" inside shared layouts (see vercel/next.js#64435).
11-
* Popstate-driven navigations are skipped so browser back/forward scroll restoration
12-
* is preserved.
25+
*
26+
* Popstate-driven navigations are skipped so browser back/forward scroll
27+
* restoration is preserved, and hash-anchor navigations are skipped so the
28+
* browser's native anchor scroll wins.
1329
*/
1430
export function ScrollToTop() {
1531
const pathname = usePathname()
16-
const isPopNavigationRef = useRef(false)
17-
18-
useEffect(() => {
19-
const onPop = () => {
20-
isPopNavigationRef.current = true
21-
}
22-
window.addEventListener('popstate', onPop)
23-
return () => window.removeEventListener('popstate', onPop)
24-
}, [])
2532

2633
useEffect(() => {
27-
if (isPopNavigationRef.current) {
28-
isPopNavigationRef.current = false
34+
if (isPopNavigation) {
35+
isPopNavigation = false
2936
return
3037
}
38+
if (window.location.hash) return
3139
window.scrollTo(0, 0)
3240
}, [pathname])
3341

0 commit comments

Comments
 (0)