diff --git a/src/components/Navigation.tsx b/src/components/Navigation.tsx index 60a45dd8f..d6b5b9e58 100644 --- a/src/components/Navigation.tsx +++ b/src/components/Navigation.tsx @@ -1,5 +1,5 @@ import clsx from 'clsx'; -import Link from 'next/link'; +import {NavigationLink} from '@/components/NavigationLink'; import {usePathname, useSearchParams} from 'next/navigation'; import {navigation, NavigationItem} from '@/data/navigation'; @@ -147,7 +147,7 @@ export function Navigation({ {separator.topics.map(topic => (
  • - { onLinkClick; @@ -161,7 +161,7 @@ export function Navigation({ )} > {topic.title} - + {topic.sections && (
  • ) )} diff --git a/src/components/NavigationLink.tsx b/src/components/NavigationLink.tsx new file mode 100644 index 000000000..0fb3556d8 --- /dev/null +++ b/src/components/NavigationLink.tsx @@ -0,0 +1,24 @@ +'use client'; + +import Link from 'next/link'; +import {useState} from 'react'; + +type NavigationLinkProps = Omit, 'prefetch'>; + +// The sidebar shows dozens of links at once, and Next's default prefetches +// the full static page for every link in the viewport: one page view fetched +// ~80 RSC payloads (2.4 MB decoded). Prefetch only once the user shows intent. +// https://nextjs.org/docs/app/guides/prefetching#hover-triggered-prefetch +export function NavigationLink(props: NavigationLinkProps) { + const [hasIntent, setHasIntent] = useState(false); + const markIntent = () => setHasIntent(true); + + return ( + + ); +}