The wire:navigate directive provides SPA-like page navigation by intercepting link clicks and loading pages in the background. Instead of full page refreshes, Livewire fetches new content and swaps it seamlessly, resulting in faster navigation and a smoother user experience.
Basic Usage
This navigation example demonstrates wire:navigate with hover prefetching and redirect functionality:
// wires/BlogPost.bxclassextends="cbwire.models.Component"{ data ={"title":"","content":""};functionsave(){ // Save blog postredirect("/blog",true);// Navigate using wire:navigate}functioncancel(){redirect("/blog",true);}}
// wires/BlogPost.cfccomponentextends="cbwire.models.Component"{data={"title" = "","content" = "" }; function save() { // Save blog post redirect("/blog", true); // Navigate using wire:navigate}functioncancel(){redirect("/blog",true);}}
What wire:navigate Does
When you add wire:navigate to a link, CBWIRE automatically:
Intercepts Clicks: Prevents browser from performing full page visits
Background Fetching: Requests new page content via AJAX with loading indicator
Seamless Swapping: Replaces URL, <title>, and <body> content without refresh
Performance Boost: Often achieves 2x faster page loads than traditional navigation
Available Modifiers
The wire:navigate directive supports one modifier:
Hover: .hover - Prefetches page content when user hovers over link for 60ms
Example: wire:navigate.hover improves perceived performance but increases server usage.
Navigation Process
Here's what happens during navigation:
User clicks a wire:navigate link
Livewire prevents default browser navigation
Loading bar appears at top of page
Page content is fetched in background
New content replaces current page seamlessly
Redirecting with Navigation
Use CBWIRE's redirect() method with navigation enabled:
Persisting Elements Across Pages
Use Alpine's x-persist to maintain elements like audio/video players:
Preserving Scroll Position
Livewire preserves page scroll by default. For specific elements, use wire:scroll:
JavaScript Hooks
Navigation triggers three lifecycle events:
Manual Navigation
Trigger navigation programmatically:
Event Listeners
Handle persistent event listeners properly:
Analytics Integration
Ensure analytics track navigation properly:
Script Handling
Control script execution across navigations:
Progress Bar Customization
Configure the loading indicator:
Custom Loader Example
Create a custom progress indicator:
wire:navigate often provides 2x faster page loads and creates a JavaScript SPA-like experience while maintaining server-side rendering benefits.
Prefetching with .hover increases server usage. Use judiciously on high-traffic sites.
Persisted elements must be placed outside CBWIRE components, typically in your main layout. Use livewire:navigated instead of DOMContentLoaded for page-specific code.
document.addEventListener('livewire:navigate', (event) => {
// Triggered when navigation starts
// Can prevent navigation: event.preventDefault()
let context = event.detail;
context.url; // URL object of destination
context.history; // True if back/forward navigation
context.cached; // True if cached version exists
});
document.addEventListener('livewire:navigating', () => {
// Triggered before HTML swap
// Good place to mutate HTML before navigation
});
document.addEventListener('livewire:navigated', () => {
// Triggered after navigation completes
// Use instead of DOMContentLoaded
});
Livewire.navigate('/new/url');
// Run once per navigation
document.addEventListener('livewire:navigated', () => {
// Page-specific code
}, { once: true });
// Persistent across navigations
document.addEventListener('livewire:navigated', () => {
// Global code
});
<head>
<!-- Cache-busted scripts with tracking -->
<script src="/app.js?id=123" data-navigate-track></script>
</head>
<body>
<!-- Run only once -->
<script data-navigate-once>
console.log('Runs only on first evaluation');
</script>
</body>