How to use external JavaScript with Livewire's wire:navigate

Livewire's wire:navigate directive provides an easy way to add SPA feel to your Laravel applications. However, when using it on pages that depend on some other JavaScript entities like Bootstrap's navbar, such interactive elements may stop working, sometimes without any error messages logged to the console. It can be frustrating when everything else seems to work perfectly fine—except your beloved UI components just stop responding.

Why Does This Happen?

Livewire’s wire:navigate works by replacing the entire body of the page whenever you load a new route, which is amazing for dynamic content updates and consequently that magical SPA experience you get for free. However, this doesn’t play well with external scripts that bind events or manipulate DOM elements during the initial page load.

The Solution: Introducing data-navigate-once

The fix is to ensure that susceptible scripts run only once—at the initial page load. This can be achieved with the data-navigate-once attribute, as shown below:

<script data-navigate-once src="{{ url('/') }}/assets/js/app.js"></script>

<script data-navigate-once> tells Livewire to process the script only during the initial page load. For subsequent page loads, Livewire will ignore these scripts. This does not only apply to external scripts, but also inline scripts:

<script data-navigate-once>
    console.log('Runs only on first load')
</script>

By using data-navigate-once, you ensure that your external scripts (like Bootstrap's JavaScript) are executed once and Livewire’s content updates that occur during wire:navigate transitions will not affect other JS functionalities.

For more details, refer to the relevant page of the official Livewire documentation.

Wanna chat about what you just read, or anything at all? Click here to tweet at me on 𝕏