Prefetching
Prefetching allows the Inertia.js client to load pages in the background before the user navigates to them. This improves perceived performance by reducing the time users wait for pages to load.
How It Works
Section titled “How It Works”When prefetching is enabled on a link, Inertia makes a background request to fetch the page data before the user clicks. The server responds normally, and the client caches the response for instant navigation.
Cross-Inertia automatically detects prefetch requests via the Purpose: prefetch header and handles them appropriately.
Frontend Setup
Section titled “Frontend Setup”Link Prefetching
Section titled “Link Prefetching”Use the prefetch prop on Link components:
import { Link } from '@inertiajs/react'
// Prefetch on hover (default behavior when prefetch is enabled)<Link href="/users/1" prefetch> View User</Link>
// Prefetch on mount (when component renders)<Link href="/dashboard" prefetch="mount"> Dashboard</Link>
// Prefetch on hover with delay<Link href="/settings" prefetch="hover"> Settings</Link>Prefetch Triggers
Section titled “Prefetch Triggers”hover: Prefetch when the user hovers over the link (most common)mount: Prefetch when the component mounts (for high-priority links)click: Prefetch on mouse down (shortest delay before navigation)
Cache Configuration
Section titled “Cache Configuration”Control how long prefetched data is cached:
import { Link } from '@inertiajs/react'
// Cache for 30 seconds<Link href="/users" prefetch cacheFor="30s"> Users</Link>
// Cache for 5 minutes<Link href="/reports" prefetch cacheFor="5m"> Reports</Link>
// Single-use (use once, then refetch)<Link href="/notifications" prefetch cacheFor={0}> Notifications</Link>Programmatic Prefetching
Section titled “Programmatic Prefetching”Use router.prefetch() for more control:
import { router } from '@inertiajs/react'
// Prefetch a pagerouter.prefetch('/users/1')
// Prefetch with optionsrouter.prefetch('/dashboard', { method: 'get', data: { filter: 'active' },})
// Prefetch with cache configurationrouter.prefetch('/users/1', {}, { cacheFor: '1m' })Prefetch State Hook
Section titled “Prefetch State Hook”Track prefetch status with usePrefetch():
import { usePrefetch } from '@inertiajs/react'
function UserLink({ userId }) { const { isPrefetching, isPrefetched } = usePrefetch(`/users/${userId}`)
return ( <Link href={`/users/${userId}`} prefetch> {isPrefetching && <Spinner />} {isPrefetched && <CheckIcon />} View User </Link> )}Backend Support
Section titled “Backend Support”Cross-Inertia automatically handles prefetch requests. No special configuration is required.
How Detection Works
Section titled “How Detection Works”Prefetch requests include the Purpose: prefetch header. Cross-Inertia detects this and:
- Processes the request normally (returns full page data)
- Logs prefetch requests distinctly for debugging
- Supports all features (partial reloads, deferred props, etc.)
Logging
Section titled “Logging”Prefetch requests are logged separately:
→ Prefetch: Users/Show (props: ['user', 'posts'])→ Inertia XHR: Users/Show (props: ['user', 'posts'])Combining with Partial Reloads
Section titled “Combining with Partial Reloads”Prefetch works with partial reloads:
// Prefetch only specific props<Link href="/users/1" prefetch only={['user', 'recentPosts']}> View User</Link>Combining with Deferred Props
Section titled “Combining with Deferred Props”Prefetch respects deferred props - they’re still loaded after the initial render:
@app.get("/users/{user_id}")async def show_user(user_id: int, inertia: InertiaDep): return inertia.render("Users/Show", { "user": get_user(user_id), # These load after render, even on prefetched pages "activity": defer(get_activity, user_id), "recommendations": defer(get_recommendations, user_id), })Real-World Examples
Section titled “Real-World Examples”Navigation Menu
Section titled “Navigation Menu”Prefetch common navigation destinations:
import { Link } from '@inertiajs/react'
function Navigation() { return ( <nav> <Link href="/dashboard" prefetch="mount"> Dashboard </Link> <Link href="/users" prefetch="hover"> Users </Link> <Link href="/settings" prefetch="hover"> Settings </Link> </nav> )}List Items
Section titled “List Items”Prefetch detail pages on hover:
import { Link } from '@inertiajs/react'
function UserList({ users }) { return ( <ul> {users.map(user => ( <li key={user.id}> <Link href={`/users/${user.id}`} prefetch="hover" cacheFor="1m" > {user.name} </Link> </li> ))} </ul> )}Tabbed Interface
Section titled “Tabbed Interface”Prefetch tab content:
import { Link, usePage } from '@inertiajs/react'
function UserTabs({ userId }) { const { url } = usePage()
return ( <div className="tabs"> <Link href={`/users/${userId}`} prefetch={url !== `/users/${userId}`} > Profile </Link> <Link href={`/users/${userId}/posts`} prefetch={url !== `/users/${userId}/posts`} > Posts </Link> <Link href={`/users/${userId}/settings`} prefetch={url !== `/users/${userId}/settings`} > Settings </Link> </div> )}Cache Management
Section titled “Cache Management”Invalidating Cache
Section titled “Invalidating Cache”Flush specific cached pages:
import { router } from '@inertiajs/react'
// Flush specific URL from cacherouter.flush('/users/1')
// Flush by cache tagsrouter.flushByCacheTags('user-1')Cache Tags
Section titled “Cache Tags”Use cache tags for grouped invalidation:
<Link href={`/users/${userId}`} prefetch cacheTags={[`user-${userId}`, 'users']}> View User</Link>// Invalidate all user-related cachesrouter.flushByCacheTags('users')Performance Considerations
Section titled “Performance Considerations”When to Prefetch
Section titled “When to Prefetch”Good candidates:
- Navigation menu items
- List item detail pages
- Next/previous pagination links
- Tabbed interface content
Avoid prefetching:
- Pages with constantly changing data
- Heavy pages that are rarely visited
- Protected pages (may prefetch unnecessarily)
Cache Duration
Section titled “Cache Duration”Choose cache duration based on data freshness needs:
// Static content - cache longer<Link href="/about" prefetch cacheFor="1h">About</Link>
// Dynamic content - cache briefly<Link href="/notifications" prefetch cacheFor="10s">Notifications</Link>
// Very dynamic - single use<Link href="/live-feed" prefetch cacheFor={0}>Live Feed</Link>Best Practices
Section titled “Best Practices”- Start with hover prefetch - It’s the safest default
- Use mount sparingly - Only for high-priority, frequently accessed pages
- Set appropriate cache times - Balance freshness vs performance
- Combine with partial reloads - Prefetch only the data you need
- Monitor network usage - Prefetching increases requests
Next Steps
Section titled “Next Steps”- Partial Reloads - Combine prefetch with partial data loading
- Configuration - Global prefetch settings