---
title: useLinkStatus
description: API Reference for the useLinkStatus hook.
url: "https://nextjs.org/docs/15/app/api-reference/functions/use-link-status"
docs_index: /docs/15/llms.txt
lastUpdated: 2025-08-14
prerequisites:
  - "API Reference: /docs/15/app/api-reference"
  - "Functions: /docs/15/app/api-reference/functions"
related:
  - /docs/15/app/api-reference/components/link
  - /docs/15/app/api-reference/file-conventions/loading
---

> For an index of all documentation, see [/docs/15/llms.txt](/docs/15/llms.txt).

The `useLinkStatus` hook lets you tracks the **pending** state of a `<Link>`. You can use it to show inline visual feedback to the user (like spinners or text glimmers) while a navigation to a new route completes.

`useLinkStatus` is useful when:

- [Prefetching](/docs/app/getting-started/linking-and-navigating#prefetching) is disabled or in progress meaning navigation is blocked.
- The destination route is dynamic **and** doesn't include a [`loading.js`](/docs/app/api-reference/file-conventions/loading) file that would allow an instant navigation.

```tsx title="app/loading-indicator.tsx" 
'use client'

import { useLinkStatus } from 'next/link'

export default function LoadingIndicator() {
  const { pending } = useLinkStatus()
  return pending ? (
    <div role="status" aria-label="Loading" className="spinner" />
  ) : null
}
```

```tsx title="app/header.tsx" 
import Link from 'next/link'
import LoadingIndicator from './loading-indicator'

export default function Header() {
  return (
    <header>
      <Link href="/dashboard" prefetch={false}>
        Dashboard <LoadingIndicator />
      </Link>
    </header>
  )
}
```

```jsx title="app/loading-indicator.js" 
'use client'

import { useLinkStatus } from 'next/link'

export default function LoadingIndicator() {
  const { pending } = useLinkStatus()
  return pending ? (
    <div role="status" aria-label="Loading" className="spinner" />
  ) : null
}
```

```jsx title="app/header.js" 
import Link from 'next/link'
import LoadingIndicator from './loading-indicator'

export default function Header() {
  return (
    <header>
      <Link href="/dashboard" prefetch={false}>
        Dashboard <LoadingIndicator />
      </Link>
    </header>
  )
}
```

> **Good to know:**
>
> - `useLinkStatus` must be used within a descendant component of a `Link` component
> - The hook is most useful when `prefetch={false}` is set on the `Link` component
> - If the linked route has been prefetched, the pending state will be skipped
> - When clicking multiple links in quick succession, only the last link's pending state is shown
> - This hook is not supported in the Pages Router and will always return `{ pending: false }`

## Parameters

```tsx
const { pending } = useLinkStatus()
```

`useLinkStatus` does not take any parameters.

## Returns

`useLinkStatus` returns an object with a single property:

| Property | Type    | Description                                  |
| -------- | ------- | -------------------------------------------- |
| pending  | boolean | `true` before history updates, `false` after |

## Example

### Inline loading indicator

It's helpful to add visual feedback that navigation is happening in case the user clicks a link before prefetching is complete.

```tsx title="app/components/loading-indicator.tsx" 
'use client'

import { useLinkStatus } from 'next/link'

export default function LoadingIndicator() {
  const { pending } = useLinkStatus()
  return pending ? (
    <div role="status" aria-label="Loading" className="spinner" />
  ) : null
}
```

```tsx title="app/shop/layout.tsx" 
import Link from 'next/link'
import LoadingIndicator from './components/loading-indicator'

const links = [
  { href: '/shop/electronics', label: 'Electronics' },
  { href: '/shop/clothing', label: 'Clothing' },
  { href: '/shop/books', label: 'Books' },
]

function Menubar() {
  return (
    <div>
      {links.map((link) => (
        <Link key={link.label} href={link.href}>
          {link.label} <LoadingIndicator />
        </Link>
      ))}
    </div>
  )
}

export default function Layout({ children }: { children: React.ReactNode }) {
  return (
    <div>
      <Menubar />
      {children}
    </div>
  )
}
```

```jsx title="app/components/loading-indicator.js" 
'use client'

import { useLinkStatus } from 'next/link'

export default function LoadingIndicator() {
  const { pending } = useLinkStatus()
  return pending ? (
    <div role="status" aria-label="Loading" className="spinner" />
  ) : null
}
```

```jsx title="app/shop/layout.js" 
import Link from 'next/link'
import LoadingIndicator from './components/loading-indicator'

const links = [
  { href: '/shop/electronics', label: 'Electronics' },
  { href: '/shop/clothing', label: 'Clothing' },
  { href: '/shop/books', label: 'Books' },
]

function Menubar() {
  return (
    <div>
      {links.map((link) => (
        <Link key={link.label} href={link.href}>
          {link.label} <LoadingIndicator />
        </Link>
      ))}
    </div>
  )
}

export default function Layout({ children }) {
  return (
    <div>
      <Menubar />
      {children}
    </div>
  )
}
```

## Gracefully handling fast navigation

If the navigation to a new route is fast, users may see an unnecessary flash of the loading indicator. One way to improve the user experience and only show the loading indicator when the navigation takes time to complete is to add an initial animation delay (e.g. 100ms) and start the animation as invisible (e.g. `opacity: 0`).

```css title="app/styles/global.css"
.spinner {
  /* ... */
  opacity: 0;
  animation:
    fadeIn 500ms 100ms forwards,
    rotate 1s linear infinite;
}

@keyframes fadeIn {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

@keyframes rotate {
  to {
    transform: rotate(360deg);
  }
}
```

| Version   | Changes                     |
| --------- | --------------------------- |
| `v15.3.0` | `useLinkStatus` introduced. |

## Next Steps

Learn more about the features mentioned in this page by reading the API Reference.

---

For a semantic overview of all documentation, see [/sitemap.md](/sitemap.md)

For an index of all available documentation, see [/docs/15/llms.txt](/docs/15/llms.txt)