Description
In the mobile navbar component, key={String(open)} is set on the root motion.div. This means the entire mobile navigation tree unmounts and remounts every time the menu opens or closes. This destroys and recreates all internal state, animation instances, and DOM nodes unnecessarily.
File to change
surfsense_web/components/homepage/navbar.tsx (line 146)
Current code
<motion.div
ref={navRef}
animate={{ borderRadius: open ? "4px" : "2rem" }}
key={String(open)}
className={cn(
"relative mx-auto flex w-full max-w-[calc(100vw-2rem)] ...",
isScrolled ? "bg-white/80 ..." : "bg-transparent ..."
)}
What to do
Remove the key prop entirely. The animate prop already handles the border-radius transition via Framer Motion:
<motion.div
ref={navRef}
animate={{ borderRadius: open ? "4px" : "2rem" }}
className={cn(
"relative mx-auto flex w-full max-w-[calc(100vw-2rem)] ...",
isScrolled ? "bg-white/80 ..." : "bg-transparent ..."
)}
If exit animations are needed for children, use AnimatePresence on the expandable content section only, not on the entire nav container.
Acceptance criteria
key={String(open)} is removed from the mobile nav container
- Mobile nav still opens/closes with smooth animation
- Nav state (scroll position, etc.) is preserved across toggles
Description
In the mobile navbar component,
key={String(open)}is set on the rootmotion.div. This means the entire mobile navigation tree unmounts and remounts every time the menu opens or closes. This destroys and recreates all internal state, animation instances, and DOM nodes unnecessarily.File to change
surfsense_web/components/homepage/navbar.tsx(line 146)Current code
What to do
Remove the
keyprop entirely. Theanimateprop already handles the border-radius transition via Framer Motion:If exit animations are needed for children, use
AnimatePresenceon the expandable content section only, not on the entire nav container.Acceptance criteria
key={String(open)}is removed from the mobile nav container