Capítulo 68 de 456
Next.js prefetches routes referenced by <Link> as they enter the viewport, downloading the assets ahead of navigation so client-side transitions feel instant. This page covers the default behavior, its scheduling, the client cache, and how to control it manually.
<Link> enters the viewport, Next.js prefetches the route behind it.loading.js boundary (then layout-to-fallback is prefetched).staleTimes.static (default 5 min) and staleTimes.dynamic (off by default) in next.config.js.partialPrefetching enabled, <Link> prefetches a per-route App Shell (shared across links to the same route) instead of the full page; rest streams after navigation.router.prefetch(): manual prefetch trigger from useRouter (next/navigation).prefetch prop on <Link>: true (resolve URL data), false (disable), null (restore default behavior).onInvalidate: callback passed to router.prefetch(href, { onInvalidate }), invoked when Next.js suspects cached data is stale.'use client'
import { useRouter } from 'next/navigation'
export function PricingCard() {
const router = useRouter()
return (
<div onMouseEnter={() => router.prefetch('/pricing')}>
<CustomLink href="/pricing">View Pricing</CustomLink>
</div>
)
}
<Link> padrão.'use client'
import Link from 'next/link'
import { useState } from 'react'
export function HoverPrefetchLink({ href, children }: { href: string; children: React.ReactNode }) {
const [active, setActive] = useState(false)
return (
<Link href={href} prefetch={active ? null : false} onMouseEnter={() => setActive(true)}>
{children}
</Link>
)
}
prefetch={null} restaura o comportamento padrão.'use client'
import { useRouter } from 'next/navigation'
import { useEffect } from 'react'
function ManualPrefetchLink({ href, children }: { href: string; children: React.ReactNode }) {
const router = useRouter()
useEffect(() => {
let cancelled = false
const poll = () => { if (!cancelled) router.prefetch(href, { onInvalidate: poll }) }
poll()
return () => { cancelled = true }
}, [href, router])
return (
<a href={href} onClick={(e) => { e.preventDefault(); router.push(href) }}>
{children}
</a>
)
}
<Link> nativo com useRouter, incluindo invalidação de cache via onInvalidate.| Static page | Dynamic page | |
|---|---|---|
| Prefetched | Sim, rota inteira | Não, exceto com loading.js |
| Client Cache TTL | 5 min (default) | Off, salvo se habilitado via staleTimes |
| Server roundtrip no clique | Não | Sim, streamed após shell |
| Context | Prefetched payload | Client Cache TTL |
|---|---|---|
Sem loading.js | Página inteira | 5 min (staleTimes.static) |
Com loading.js | Layout até o primeiro loading boundary | Off por padrão (staleTimes.dynamic) |
useEffect ou Server Action disparada por Client Component.prefetch={false} ou hover-triggered prefetch.<Link> sem necessidade: opta o dev por manter manualmente prefetch, invalidação de cache e acessibilidade.layout/page corre durante prefetch → mover para componente Client com useEffect.next dev.loading.js.prefetch={false} desliga completamente; hover-triggered prefetch é o meio-termo recomendado para volume alto de links.useEffect/Server Action para não disparar no prefetch.searchParams/params) no prefetch com prefetch={true} sob Partial Prefetching.