The @persist directive preserves elements across page navigations when using wire:navigate, maintaining their state and avoiding re-initialization.
Wrap an element with @persist and provide a unique name to preserve it across page visits:
@persist('player')
<audio src="{{ $episode->file }}" controls></audio>
@endpersistWhen navigating to a new page that also contains a persisted element with the same name, Livewire reuses the existing DOM element instead of creating a new one. For an audio player, this means playback continues uninterrupted.
[!tip] Requires wire:navigate The@@persistdirective only works when navigation is handled by Livewire'swire:navigatefeature. Standard page loads will not preserve elements.
Audio/video players
@persist('podcast-player')
<audio src="{{ $episode->audio_url }}" controls></audio>
@endpersistChat widgets
@persist('support-chat')
<div id="chat-widget">
<!-- Chat interface... -->
</div>
@endpersistThird-party widgets
@persist('analytics-widget')
<div id="analytics-dashboard">
<!-- Complex widget that's expensive to initialize... -->
</div>
@endpersistPersisted elements should typically be placed outside Livewire components, commonly in your main layout:
<!-- resources/views/layouts/app.blade.php -->
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{ $title ?? config('app.name') }}</title>
@vite(['resources/css/app.css', 'resources/js/app.js'])
@livewireStyles
</head>
<body>
<main>
{{ $slot }}
</main>
@persist('player')
<audio src="{{ $episode->file }}" controls></audio>
@endpersist
@livewireScripts
</body>
</html>For scrollable persisted elements, add wire:navigate:scroll to maintain scroll position:
@persist('scrollable-list')
<div class="overflow-y-scroll" wire:navigate:scroll>
<!-- Scrollable content... -->
</div>
@endpersistInside persisted elements, use wire:current instead of server-side conditionals to highlight active links:
@persist('navigation')
<nav>
<a href="/dashboard" wire:navigate wire:current="font-bold">Dashboard</a>
<a href="/posts" wire:navigate wire:current="font-bold">Posts</a>
<a href="/users" wire:navigate wire:current="font-bold">Users</a>
</nav>
@endpersistLearn more about wire:current →
When navigating with wire:navigate: 1. Livewire looks for elements with matching @persist names on both pages 2. If found, the existing element is moved to the new page's DOM 3. The element's state, event listeners, and Alpine data are preserved
Learn more about navigation →
@persist(string $key)
<!-- Content -->
@endpersist| Parameter | Type | Default | Description |
|---|---|---|---|
$key | string | *required* | A unique name identifying the element to persist across page navigations |