Laravel Blade components revolutionize the way developers create modular and reusable UI elements, drastically reducing code duplication while improving maintainability. If you've worked with modern front-end frameworks like Vue.js or React, you'll find Blade components offer a similar component-based approach—but designed specifically for server-side rendering in Laravel applications.
What Are Blade Components?
A Blade component is a self-contained, reusable piece of UI that encapsulates both markup and logic. Think of components as building blocks for your interface—buttons, modals, alerts, cards, navigation bars, and form inputs can all be transformed into Blade components.
Key benefits include:
- Code reusability across multiple views
- Consistent UI patterns throughout your application
- Easier maintenance with centralized component logic
- Better testing with isolated component functionality
- Improved collaboration among development teams
Creating Your First Blade Component
Laravel 12 makes component creation straightforward with Artisan commands. Let's create an Alert component to display success, error, or informational messages.
Generate the Component
Run the following Artisan command in your terminal:
php artisan make:component Alert
This command generates two essential files:
app/View/Components/Alert.php– Contains the component's PHP logic and data handlingresources/views/components/alert.blade.php– Holds the component's HTML template
Define Component Logic with Type-Safe Properties
In Laravel 12, you can leverage PHP 8.2+ features for cleaner component classes. Open app/View/Components/Alert.php:
namespace App\View\Components;
use Illuminate\Contracts\View\View;
use Illuminate\View\Component;
class Alert extends Component
{
/**
* Create a new component instance.
*/
public function __construct(
public string $type = 'info',
public ?string $title = null,
public bool $dismissible = false
) {}
/**
* Get the view / contents that represent the component.
*/
public function render(): View
{
return view('components.alert');
}
/**
* Get the alert icon based on type.
*/
public function icon(): string
{
return match($this->type) {
'success' => '✓',
'error' => '✕',
'warning' => '⚠',
default => 'ℹ',
};
}
}
Laravel 12 improvements used here:
- Constructor property promotion for cleaner syntax
- Type declarations for better IDE support
- Match expressions for conditional logic
- Return type declarations for View contracts
Build the Component View
Create the template in resources/views/components/alert.blade.php:
@props(['type' => 'info', 'title' => null, 'dismissible' => false])
<div {{ $attributes->merge(['class' => "alert alert-{$type} border-l-4 p-4 rounded-lg"]) }} role="alert">
<div class="flex items-start">
<div class="flex-shrink-0">
<span class="text-xl">{{ $icon() }}</span>
</div>
<div class="ml-3 flex-1">
@if($title)
<h3 class="text-sm font-medium mb-1">{{ $title }}</h3>
@endif
<div class="text-sm">
{{ $slot }}
</div>
</div>
@if($dismissible)
<button type="button" class="ml-auto" onclick="this.parentElement.parentElement.remove()">
<span class="text-xl">×</span>
</button>
@endif
</div>
</div>
Using Components in Blade Templates
Now you can use your Alert component anywhere in your Laravel 12 application:
{{-- Basic usage --}}
<x-alert type="success">
Your profile has been updated successfully!
</x-alert>
{{-- With title and dismissible option --}}
<x-alert type="error" title="Validation Failed" :dismissible="true">
Please check the form for errors and try again.
</x-alert>
{{-- Passing additional classes --}}
<x-alert type="warning" class="mb-4 shadow-lg">
Your session will expire in 5 minutes.
</x-alert>
Anonymous Blade Components
For simpler components without complex logic, Laravel 12 supports anonymous components—Blade templates without a corresponding PHP class. These are perfect for presentational components.
Creating an Anonymous Component
Create a file directly in resources/views/components/button.blade.php:
@props([
'type' => 'button',
'variant' => 'primary',
'size' => 'md',
])
@php
$classes = match($variant) {
'primary' => 'bg-blue-600 hover:bg-blue-700 text-white',
'secondary' => 'bg-gray-600 hover:bg-gray-700 text-white',
'danger' => 'bg-red-600 hover:bg-red-700 text-white',
'success' => 'bg-green-600 hover:bg-green-700 text-white',
default => 'bg-blue-600 hover:bg-blue-700 text-white',
};
$sizes = match($size) {
'sm' => 'px-3 py-1.5 text-sm',
'md' => 'px-4 py-2 text-base',
'lg' => 'px-6 py-3 text-lg',
default => 'px-4 py-2 text-base',
};
@endphp
<button
type="{{ $type }}"
{{ $attributes->merge(['class' => "rounded-lg font-medium transition-colors duration-200 {$classes} {$sizes}"]) }}
>
{{ $slot }}
</button>
Usage Examples
{{-- Default button --}}
<x-button>Submit</x-button>
{{-- Different variants and sizes --}}
<x-button variant="danger" size="lg">Delete Account</x-button>
{{-- With additional attributes --}}
<x-button variant="secondary" onclick="window.history.back()">
Go Back
</x-button>
{{-- With Alpine.js integration --}}
<x-button variant="success" x-on:click="saveForm">
Save Changes
</x-button>
Advanced Component Techniques
Slots and Slot Attributes
Laravel 12 allows you to define multiple named slots for complex component layouts:
{{-- resources/views/components/card.blade.php --}}
<div {{ $attributes->merge(['class' => 'bg-white rounded-lg shadow-md overflow-hidden']) }}>
@if(isset($header))
<div class="px-6 py-4 bg-gray-50 border-b">
{{ $header }}
</div>
@endif
<div class="px-6 py-4">
{{ $slot }}
</div>
@if(isset($footer))
<div class="px-6 py-4 bg-gray-50 border-t">
{{ $footer }}
</div>
@endif
</div>
Usage with named slots:
<x-card>
<x-slot:header>
<h2 class="text-xl font-bold">User Profile</h2>
</x-slot:header>
<p>This is the main content of the card.</p>
<x-slot:footer>
<x-button variant="primary">Edit Profile</x-button>
</x-slot:footer>
</x-card>
Component Attributes API
Laravel 12's attributes API provides powerful methods for managing component attributes:
{{-- Merge classes conditionally --}}
<div {{ $attributes->class([
'base-class',
'active-class' => $isActive,
'error-class' => $hasError,
]) }}>
{{ $slot }}
</div>
{{-- Filter specific attributes --}}
<div {{ $attributes->only(['class', 'id']) }}>
<input {{ $attributes->except(['class', 'id']) }} />
</div>
Dynamic Components
Render components dynamically based on variables or conditions:
<x-dynamic-component :component="$componentName" :type="$alertType">
{{ $message }}
</x-dynamic-component>
Best Practices for Blade Components
- Keep components focused – Each component should have a single responsibility
- Use type hints – Leverage PHP 8.2+ type declarations for better IDE support
- Document props – Add DocBlocks explaining component parameters
- Organize by feature – Group related components in subdirectories
- Test components – Write unit tests for component logic and rendering
- Use anonymous components for simple presentational elements
- Leverage class-based components when you need complex logic or computed properties
Component Organization Structure
resources/views/components/
├── forms/
│ ├── input.blade.php
│ ├── select.blade.php
│ └── textarea.blade.php
├── layout/
│ ├── header.blade.php
│ ├── footer.blade.php
│ └── sidebar.blade.php
├── ui/
│ ├── button.blade.php
│ ├── card.blade.php
│ └── modal.blade.php
└── alerts/
└── alert.blade.php
Access nested components with dot notation:
<x-forms.input name="email" type="email" />
<x-ui.card>Content here</x-ui.card>
Conclusion
Blade components are an essential feature in Laravel 12 that dramatically improve code organization, reusability, and maintainability. By leveraging class-based components for complex logic and anonymous components for simple UI elements, you can build scalable applications with consistent design patterns.
Whether you're building a small project or a large enterprise application, mastering Blade components will make your codebase cleaner, more testable, and easier to maintain. Start by converting repetitive UI elements into components, and gradually build a comprehensive component library for your Laravel applications.