useLinkStatus in Next.js tells a component whether the Link it is nested inside is still navigating. Render a small indicator as a child of that link, and it can show a loading state for exactly as long as the navigation takes, then disappear on its own once the new page has rendered.
// app/components/loading-indicator.tsx
"use client";
import { useLinkStatus } from "next/link";
export default function LoadingIndicator() {
const { pending } = useLinkStatus();
return pending ? <span role="status">Loading…</span> : null;
}This hook only works in a Client Component, so the file needs a client directive. It has to be called from a component rendered inside a Link, not from the link itself, and it only returns one value: pending, a boolean with no parameters to configure. It was introduced as a stable API in Next.js 15.3 and carries no experimental label in Next.js 16.
Rendering the indicator inside a link
Place the indicator component as a child of the link it should describe, right alongside the link's own visible text. Next.js renders it in place, so it needs no extra positioning of its own to sit correctly inside the clickable area.
// app/nav.tsx
import Link from "next/link";
import LoadingIndicator from "./components/loading-indicator";
export default function Nav() {
return (
<Link href="/reports" prefetch={false}>
Reports <LoadingIndicator />
</Link>
);
}Click "Reports" and the indicator appears for as long as the navigation takes, then disappears once the new page has rendered. Setting prefetch={false} here matters: a fully prefetched link often completes so fast that there is nothing meaningful to show, so this hook is most useful on links that are not prefetched or that lead to a route without a loading file of its own. On a route that is already prefetched, seeing no indicator at all is expected, not a sign that something is broken.
Making the indicator accessible
The role="status" attribute in the example above announces the text to a screen reader when it appears, and the visible word "Loading…" means the state is not shown through color or an icon alone. Do not hide this element from assistive technology, since a reader who cannot see the page still needs to know a navigation is in progress the same way a sighted reader would from the visible text.
Keep the indicator's layout space reserved even while hidden, rather than letting the surrounding text jump when it appears and disappears. A fixed-width span or a reserved gap next to the link text avoids that shift, which matters more the more often a given link gets clicked.
This hook pairs naturally with a link that is not fully prefetched, covered in How Prefetching Works in Next.js and How to Control It. For the full set of props a link accepts, see The Next.js Link Component: Props and Behavior Explained.
Rune AI
Key Insights
- useLinkStatus must be called from a component nested inside a Link, not the Link itself.
- It returns only one value, pending, with no parameters accepted.
- It works best when a link is not fully prefetched, such as with prefetch set to false.
- The hook always returns pending as false in the Pages Router.
- Add an accessible name and a visible cue, since the docs' own example hides the indicator from screen readers.
Frequently Asked Questions
Can I call useLinkStatus on the Link component itself?
Will the indicator show for every link?
Does this hook work in the Pages Router?
Conclusion
useLinkStatus reads whether the Link it is nested inside is still navigating, returning a single pending value. Render a small indicator component inside the link to show that state, and give it an accessible name and a non-color cue so a screen reader and a reader with low vision both notice it.
More in this topic
`generateMetadata` Explained with Real Examples
What generateMetadata does, when it runs, and how to use it for real routes: awaited params, deduplicated data fetching, extending parent metadata, and returning a 404 from metadata.
Canonical URLs in Next.js: `metadataBase`, `alternates.canonical`, and Dynamic Pages
How canonical URLs work in the Next.js App Router: setting metadataBase once, writing alternates.canonical per route, handling dynamic segments, and what happens when the base URL is missing.
Open Graph and Twitter Card Metadata in Next.js
How to write Open Graph and Twitter card metadata in the Next.js App Router: the openGraph and twitter fields, automatic card defaults, article tags, and image merge rules.