Livewire wire:navigate: Blade Views ↔ Livewire Runtime – Should navigation be global or selective?
0 reputation · 26 Oct 2024, 15:56 UTC
0 reputation · 26 Oct 2024, 15:56 UTC
Enable smooth, SPA‑like navigation between Laravel routes that return Blade views containing Livewire components.
Livewire v3 introduces wire:navigate to intercept link clicks and perform a background fetch, swapping the <body> without a full reload. The feature merges the <head> and preserves previously loaded scripts, which can affect third‑party JavaScript that expects a full page load. Additionally, state that lives in browser memory (e.g., open modals, Alpine.js component state) does not persist automatically; developers must use @persist or listen to livewire:navigated events. A key decision is whether to apply wire:navigate globally across all links or selectively to avoid breaking scripts that rely on a full reload.
wire:navigate be enabled on every link by default, or should developers manually add the attribute to only those that require SPA‑like behavior?DOMContentLoaded be reliably re‑initialized after a wire:navigate swap?wire:navigate transitions while avoiding unnecessary asset duplication?30775 reputation · 26 Oct 2024, 17:46 UTC
You should apply wire:navigate selectively. While the goal is an SPA-like experience, applying it globally by default often breaks third-party JavaScript, analytics trackers, and payment gateways that rely on a full page lifecycle (DOMContentLoaded). Enable it for primary application links and internal navigation, but omit it for external links, file downloads, and pages containing heavy, non-Livewire third-party widgets.
Livewire v3 achieves this effect by fetching the next page in the background and swapping the <body> content while merging the <head>. Because the browser does not perform a hard refresh, standard window-load events do not fire on subsequent navigations.
Scripts that initialize once on page load will fail to run after a wire:navigate swap. To fix this, move your initialization logic into a listener for the livewire:navigated event.
<script>
document.addEventListener('livewire:navigated', () => {
// Re-initialize your third-party widgets here
initMyPlugin();
});
</script>
Note: Ensure your initialization function is idempotent or checks if the plugin is already active to avoid double-binding on the initial page load.
To prevent asset duplication and maintain state, follow these structural patterns:
@push or @section to place per-page assets in the <head>. Livewire merges the head, ensuring assets are added once and not duplicated on every swap.@persist directive.@persist for Alpine components that need to maintain state across routes.console.log inside a livewire:navigated listener and verify it triggers upon clicking a wire:navigate link.<head> after navigating between three different pages; verify that CSS files are not being appended repeatedly.window.onload.Diagnostic Detail Required: Are you using any specific third-party libraries (e.g., Google Maps, Stripe, or complex Chart.js setups) that manage their own DOM lifecycle? This may necessitate a more aggressive selective approach.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.