Livewire Partials provide a structured and explicit way to update specific DOM fragments of a Livewire component instead of re-rendering the entire component tree.
This is especially useful for complex components such as data tables, where partial updates significantly improve performance and user experience.
- PHP 8.3+
- Livewire ^4.0
composer require power-components/partialsImport the package JavaScript once in your application entrypoint.
resources/js/app.js
import '../../../vendor/power-components/partials/resources/js/index.js'You may disable partial rendering globally via environment configuration.
.env
POWERGRID_PARTIALS_ENABLED=falseWhen disabled, Livewire behaves exactly as usual and no partial payloads are generated.
A partial is a named DOM fragment explicitly marked for selective updates.
Only the HTML associated with that fragment is re-rendered and sent to the frontend.
Partials are identified by a unique name and mapped to a view or raw HTML.
Partials work best when you extract your DOM regions into separate Blade files or components. This allows you to reuse the same view for both the initial render and subsequent partial updates.
resources/views/components/table/index.blade.php
<div>
<table>
<thead wire:partial="table-thead">
<x-table.tr :__partial="$this" />
</thead>
<tbody wire:partial="table-tbody">
<x-table.tbody :__partial="$this" />
</tbody>
</table>
</div>When a component is rendered normally (initial page load or full Livewire update), the $this variable refers to the Livewire component instance.
However, during a partial update, the partial is rendered in isolation, and the package automatically injects the component instance into a variable named $__partial.
To make your sub-views (partials) compatible with both scenarios, you should:
- Accept a
__partialattribute in your Blade components (using@props). - Pass
:__partial="$this"when including them in the main view. - Use
$__partialinside the sub-view to access the component.
resources/views/components/table/tbody.blade.php
@props(['__partial'])
@foreach($__partial->users as $user)
<tr>
<td>{{ $user->id }}</td>
<td>{{ $user->name }}</td>
</tr>
@endforeachUse the partials() helper to register one or more partials during a component action.
public function sortBy(string $field): void
{
$this->sortField = $field;
partials($this)
->partial(
'table-thead',
'components.table.thead',
[
'tableName' => $this->tableName,
]
)
->partial(
'table-tbody',
'components.table.tbody',
[
'tableName' => $this->tableName,
]
);
}The component instance is automatically available inside partial views as $__partial.
For simple scenarios, partials can be registered declaratively using the PartialRender attribute.
use PowerComponents\Partials\Attribute\PartialRender;
#[PartialRender('components.table.tbody', 'table-tbody')]
public function sortBy(string $field): void
{
$this->sortField = $field;
}When the method is executed, the specified view is automatically rendered and dispatched as a partial update.
You may exclude specific elements from being re-rendered during partial updates using wire:partial.ignore. This is particularly useful for elements that maintain their own internal state (like Alpine.js components, checkboxes, or focus) that would otherwise be lost if the element's HTML were replaced.
This directive must be used on an element that is inside a wire:partial block.
For it to work correctly, the element must have a unique identification (key). The package attempts to automatically identify it via wire:key or id attributes. If neither is present, you must provide a custom key directly in the directive.
<thead wire:partial="table-thead">
<tr>
<!-- ✅ The ID ensures ignore works -->
<th id="select-all-column" wire:partial.ignore>
<input type="checkbox" x-model="selectAll" />
</th>
<th>Name</th>
</tr>
</thead>
@foreach($users as $user)
<div wire:key="user-{{ $user->id }}">
<!-- ✅ Ignoring only the first element to preserve its state -->
<div
@if($loop->first) wire:partial.ignore="first-user-bio" @endif
>
{{ $user->bio }}
</div>
</div>
@endforeachUsing explicit keys (e.g., wire:partial.ignore="my-key") is the best practice as it makes the relationship between the ignored element and its state more predictable and robust.
- Backend: The package detects the
wire:partial.ignoredirective and replaces the element's content with a lightweight placeholder (<!--PARTIAL:IGNORE:key-->). - Frontend: Before applying the update, the JavaScript bridge captures the current
innerHTMLof the ignored element. - Morphing: During the DOM morphing process, the ignored element itself is skipped (it's not updated), and its original content is restored if necessary.
- Preservation: Event listeners, local state, and Alpine.js data remain completely intact because the DOM element is never destroyed or replaced.
- Created by Luan Freitas
Dan Harrin proposed the original concept of the partials. The code for this package is based on the code he kindly shared with us.
Notice of Non-Affiliation and Disclaimer: Partials are not affiliated with, associated with, endorsed by, or in any way officially connected with the Laravel Livewire - copyright by Caleb Porzio. Laravel is a trademark of Taylor Otwell.