Imagine you have big data that needs to be loaded into a table. Besides the Lazy Loading component, another method uses wire:loading directive which has a bit more features.
First, add a div element with the wire:loading directive above the table.
resources/views/livewire/products.blade.php:
<div class="space-y-6"> <div class="space-x-8"> // ... </div> <div class="text-red-600" wire:loading>Loading...</div> <div class="min-w-full align-middle"> // ... </div> {{ $products->links() }}</div>
Simulate longer loading by adding sleep(1) to the Livewire component render method. Then try to search, and you should see a red text saying Loading....

The wire:loading directive also accepts adding or removing class parameters. For example, we can add opacity to the table while loading.
resources/views/livewire/products.blade.php:
<div class="space-y-6"> // ... <div class="text-red-600" wire:loading>Loading...</div> <div class="min-w-full align-middle" wire:loading.class="opacity-50"> // [tl! highlight] // ... </div> {{ $products->links() }}</div>

You can target a specific action by adding the wire:target="methodName" directive.
<form wire:submit="save"> <!-- ... --> <button type="submit">Save</button> <button type="button" wire:click="remove">Remove</button> <div wire:loading wire:target="remove"> Removing post... </div></form>
You can read more about Loading States in the official documentation.