← Back
Edit Post
Title
Description
Track Link pending state, SortButton pattern, prefetch={false} for visible feedback.
Content
Markdown supported
# useLinkStatus for Link Pending State The `useLinkStatus` hook provides pending state for `<Link>` navigations. It must be used inside a descendant component of `Link`. ## When to Use Use `useLinkStatus` when: - Prefetching is disabled or in progress - The destination route is dynamic and doesn't have a `loading.js` - You want inline feedback (spinner, shimmer) on the clicked link itself ## The Pattern ```tsx 'use client'; import Link, { useLinkStatus } from 'next/link'; import { Loader2, ArrowUpDown } from 'lucide-react'; function SortIndicator({ icon: Icon, label }: { icon: typeof ArrowUpDown; label: string }) { const { pending } = useLinkStatus(); return ( <> {pending ? <Loader2 className="size-4 animate-spin" /> : <Icon className="size-4" />} <span>{label}</span> </> ); } export function SortButton() { return ( <Link href="/dashboard?sort=newest" prefetch={false} className="..."> <SortIndicator icon={ArrowUpDown} label="Newest" /> </Link> ); } ``` ## Key Points 1. **Must be a Link descendant** - `useLinkStatus` only works inside a component rendered within `<Link>` 2. **Use `prefetch={false}`** - If the route is prefetched, pending state is skipped 3. **Extract to child component** - The hook tracks the parent Link's navigation state 4. **Style as Link** - Use `buttonVariants` from shadcn/ui to style Links as buttons ## vs useTransition + router.push | Approach | Pros | Cons | |----------|------|------| | `useLinkStatus` | Simpler, no state management, declarative | Must use `<Link>`, no optimistic updates | | `useTransition` + `router.push` | Full control, optimistic updates possible | More boilerplate, imperative | Choose `useLinkStatus` for simple navigation feedback. Use `useTransition` when you need optimistic state updates during navigation.
Published
Save Changes
Cancel