title | description |
---|---|
useLinkStatus |
API Reference for the useLinkStatus hook. |
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 ? <div>Loading...</div> : null
}
'use client'
import { useLinkStatus } from 'next/navigation'
export default function LoadingIndicator() {
const { pending } = useLinkStatus()
return pending ? <div>Loading...</div> : 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>
)
}
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 }
const { pending } = useLinkStatus()
useLinkStatus
does not take any parameters.
useLinkStatus
returns an object with a single property:
Property | Type | Description |
---|---|---|
pending | boolean | true before history updates, false after |
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 { useSearchParams, useLinkStatus } from 'next/navigation'
import Link from 'next/link'
import { Suspense } from 'react'
function LoadingIndicator() {
const { pending } = useLinkStatus()
return pending ? <span>⌛</span> : null
}
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>
)
}
'use client'
import { useSearchParams, useLinkStatus } from 'next/navigation'
import Link from 'next/link'
import { Suspense } from 'react'
function LoadingIndicator() {
const { pending } = useLinkStatus()
return pending ? <span>⌛</span> : null
}
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 }) {
const products = await fetchProducts(category)
return (
<ul>
{products.map((product) => (
<li key={product}>{product}</li>
))}
</ul>
)
}
export default async function ProductCategories({ searchParams }) {
const { category } = await searchParams
return (
<Suspense fallback={<PageSkeleton />}>
<MenuBar />
<ProductList category={category} />
</Suspense>
)
}
Version | Changes |
---|---|
v15.3.0 |
useLinkStatus introduced. |