`useLinkStatus`: Showing Pending State During Navigation

useLinkStatus tells a component inside a Link whether that navigation is still pending, which is how you show a loading indicator on a slow link.

7 min read

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.tsxApp.tsx
// 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.

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.tsxApp.tsx
// 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

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.
RunePowered by Rune AI

Frequently Asked Questions

Can I call useLinkStatus on the Link component itself?

No. It has to be called from a descendant component rendered inside the Link, not the Link component itself.

Will the indicator show for every link?

Not always. If a route was already prefetched, the navigation can complete so fast that the pending state never appears, which is expected behavior rather than a bug.

Does this hook work in the Pages Router?

No. It always returns pending as false there. It only reflects real navigation state in the App 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.