The #[Session] attribute persists a property's value in the user's session, maintaining it across page refreshes and navigation.
Apply the #[Session] attribute to any property that should persist in the session:
<?php // resources/views/components/post/⚡index.blade.php
use Livewire\Attributes\Session;
use Livewire\Attributes\Computed;
use Livewire\Component;
use App\Models\Post;
new class extends Component {
#[Session] // [tl! highlight]
public $search = '';
#[Computed]
public function posts()
{
return $this->search === ''
? Post::all()
: Post::where('title', 'like', "%{$this->search}%")->get();
}
};
?>
<div>
<input type="text" wire:model.live="search" placeholder="Search posts...">
@foreach($this->posts as $post)
<div wire:key="{{ $post->id }}">{{ $post->title }}</div>
@endforeach
</div>After a user enters a search value, they can refresh the page or navigate away and return—the search value will be preserved.
Every time the property changes, Livewire stores its new value in the user's session. When the component loads, Livewire fetches the value from the session and initializes the property with it.
This creates a persistent user experience without modifying the URL.
Both #[Session] and #[Url] persist property values, but with different trade-offs:
| Feature | #[Session] | #[Url] |
|---|---|---|
| Persists across refreshes | âś… | âś… |
| Persists when sharing URL | ❌ | ✅ |
| Keeps URL clean | ✅ | ❌ |
| Visible to user | ❌ | ✅ |
| Shareable state | ❌ | ✅ |
Use #[Session] when you want persistence without cluttering the URL or when state shouldn't be shareable.
By default, Livewire generates session keys using the component and property names. You can customize this:
<?php // resources/views/components/post/⚡index.blade.php
use Livewire\Attributes\Session;
use Livewire\Component;
new class extends Component {
#[Session(key: 'post_search')] // [tl! highlight]
public $search = '';
};The property will be stored in the session using the key post_search.
You can generate keys dynamically using other properties:
<?php // resources/views/components/post/⚡index.blade.php
use Livewire\Attributes\Session;
use Livewire\Component;
use App\Models\Author;
new class extends Component {
public Author $author;
#[Session(key: 'search-{author.id}')] // [tl! highlight]
public $search = '';
};If $author->id is 4, the session key becomes search-4. This allows different session values per author.
Use #[Session] when:
Here's a practical example of persisting dashboard filters:
<?php // resources/views/pages/⚡dashboard.blade.php
use Livewire\Attributes\Session;
use Livewire\Attributes\Computed;
use Livewire\Component;
use App\Models\Transaction;
new class extends Component {
#[Session]
public $dateRange = '30days';
#[Session]
public $category = 'all';
#[Session]
public $sortBy = 'date';
#[Computed]
public function transactions()
{
return Transaction::query()
->when($this->dateRange === '30days', fn($q) => $q->where('created_at', '>=', now()->subDays(30)))
->when($this->category !== 'all', fn($q) => $q->where('category', $this->category))
->orderBy($this->sortBy)
->get();
}
};
?>
<div>
<select wire:model.live="dateRange">
<option value="7days">Last 7 days</option>
<option value="30days">Last 30 days</option>
<option value="year">This year</option>
</select>
<select wire:model.live="category">
<option value="all">All categories</option>
<option value="income">Income</option>
<option value="expense">Expense</option>
</select>
<select wire:model.live="sortBy">
<option value="date">Date</option>
<option value="amount">Amount</option>
</select>
@foreach($this->transactions as $transaction)
<div wire:key="{{ $transaction->id }}">{{ $transaction->description }}</div>
@endforeach
</div>Users can set their preferred filters and they'll persist across sessions, page refreshes, and navigation.
[!warning] Don't store large amounts of data Laravel sessions are loaded into memory during every request. Storing too much in a user's session can slow down your entire application for that user. Avoid storing large collections or objects.
Good uses:
Bad uses:
[!tip] Alternative: URL persistence If you want state to be shareable via URL or bookmarkable, consider using the [#[Url]attribute](/docs/4.x/url) instead of#[Session]. URL parameters persist state in the address bar while session properties keep the URL clean.
#[Session(
?string $key = null,
)]| Parameter | Type | Default | Description |
|---|---|---|---|
$key | ?string | null | Custom session key (auto-generated if not provided) |