Reusable UI with Blade Components
Blade components let you build reusable UI elements with encapsulated logic and clean interfaces — similar to React or Vue components.
Anonymous Components
Create a file in resources/views/components/:
{{-- resources/views/components/alert.blade.php --}}
@props([
'type' => 'info',
'dismissible' => false,
])
@php
$classes = match($type) {
'success' => 'bg-green-100 text-green-800 border-green-300',
'error' => 'bg-red-100 text-red-800 border-red-300',
'warning' => 'bg-yellow-100 text-yellow-800 border-yellow-300',
default => 'bg-blue-100 text-blue-800 border-blue-300',
};
@endphp
<div {{ $attributes->merge(['class' => "p-4 rounded-lg border {$classes}"]) }}>
{{ $slot }}
@if($dismissible)
<button onclick="this.parentElement.remove()">✕</button>
@endif
</div>
Usage:
<x-alert type="success">Post published successfully!</x-alert>
<x-alert type="error" dismissible>Something went wrong.</x-alert>
<x-alert type="warning" class="mt-4">Please review your input.</x-alert>
Named Slots
{{-- resources/views/components/card.blade.php --}}
<div class="bg-white rounded-xl shadow-sm overflow-hidden">
@isset($header)
<div class="px-6 py-4 border-b">{{ $header }}</div>
@endisset
<div class="p-6">{{ $slot }}</div>
@isset($footer)
<div class="px-6 py-4 bg-gray-50 border-t">{{ $footer }}</div>
@endisset
</div>
<x-card>
<x-slot:header>
<h2 class="text-lg font-semibold">User Profile</h2>
</x-slot:header>
<p>Main content goes here.</p>
<x-slot:footer>
<button class="btn-primary">Save Changes</button>
</x-slot:footer>
</x-card>
Class-Based Components
For components with complex logic:
php artisan make:component PostCard
class PostCard extends Component
{
public function __construct(
public Post $post,
public bool $showExcerpt = true,
) {}
public function readingTime(): int
{
return ceil(str_word_count($this->post->body) / 200);
}
public function render(): View
{
return view('components.post-card');
}
}
Components make your Blade templates composable and maintainable at scale.