useLinkStatus
useLinkStatus
is a Client Component hook that lets you track the loading state of a Link
component during navigation. It can be used to show loading indicators during page transitions, especially when prefetching is disabled, or the linked route does not have any loading states.
'use client'
import { useLinkStatus } from 'next/navigation'
export default function LoadingIndicator() {
const { pending } = useLinkStatus()
return pending ? <span>⌛</span> : null
}
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 aLink
component- The hook is most useful when
prefetch={false}
is set on theLink
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
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 |
Examples
Improving the user experience when navigating with new query parameters
In this example, navigating between categories updates the query string (e.g. ?category=books). However, the page may appear unresponsive because the <PageSkeleton />
fallback won't replace the existing content (see preventing unwanted loading indicators).
You can use the useLinkStatus
hook to render a lightweight loading indicator next to the active link and provide immediate feedback to the user while the data is being fetched.
'use client'
import { useLinkStatus } from 'next/navigation'
export default function LoadingIndicator() {
const { pending } = useLinkStatus()
return pending ? <span>⌛</span> : null
}
import { useSearchParams } from 'next/navigation'
import Link from 'next/link'
import { Suspense } from 'react'
import LoadingIndicator from './loading-indicator'
function MenuBar() {
return (
<div>
<Link href="?category=electronics">
Electronics <LoadingIndicator />
</Link>
<Link href="?category=clothing">
Clothing <LoadingIndicator />
</Link>
<Link href="?category=books">
Books <LoadingIndicator />
</Link>
</div>
)
}
async function ProductList({ category }: { category: string }) {
const products = await fetchProducts(category)
return (
<ul>
{products.map((product) => (
<li key={product}>{product}</li>
))}
</ul>
)
}
export default async function ProductCategories({
searchParams,
}: {
searchParams: Promise<{
category: string
}>
}) {
const { category } = await searchParams
return (
<Suspense fallback={<PageSkeleton />}>
<MenuBar />
<ProductList category={category} />
</Suspense>
)
}
Version | Changes |
---|---|
v15.3.0 | useLinkStatus introduced. |
Was this helpful?