"use client"; import { AnimatePresence, motion, useReducedMotion } from "framer-motion"; import { LayoutRouterContext } from "next/dist/shared/lib/app-router-context.shared-runtime"; import { usePathname } from "next/navigation"; import { useContext, useState, type ReactNode } from "react"; /** * App Router swaps in the new page's content as soon as you navigate, so the * outgoing page would normally vanish before it can animate out. `FrozenRouter` * pins the layout-router context to the value it had when this instance * mounted, keeping the *old* subtree rendered while its exit animation plays. */ function FrozenRouter({ children }: { children: ReactNode }) { const context = useContext(LayoutRouterContext); // Freeze the context captured at mount so the outgoing subtree keeps // rendering (with its old route data) while its exit animation plays. const [frozen] = useState(context); if (!frozen) { return <>{children}; } return {children}; } /** * One unified page transition on every navigation: the old page animates out * (blur + rise up) before the new page animates in (blur + rise from below). */ export default function SiteTemplate({ children }: { children: ReactNode }) { const reducedMotion = useReducedMotion(); const pathname = usePathname(); return ( {children} ); }