In modern web applications, repetitive UI patterns (buttons, modal dialogs, alert cards, form inputs, navigation menus) should never be duplicated across dozens of templates. Blade Components provide a React/Vue-like custom tag syntax (<x-alert>) directly inside PHP views, complete with attributes, props, and multi-slot layouts.
Create your master HTML shell inside resources/views/components/layout.blade.php:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{{ $title ?? 'Veewom Application' }}</title>
@vite(['resources/css/app.css', 'resources/js/app.js'])
</head>
<body class="bg-gray-50 text-gray-900">
<!-- Top Navigation -->
<nav class="bg-white border-b px-6 py-4">
<a href="/" class="font-bold text-xl text-red-900">Veewom</a>
</nav>
<!-- Optional Named Header Slot -->
@isset($header)
<header class="bg-white shadow-sm py-4 px-6 mb-6">
{{ $header }}
</header>
@endisset
<!-- Default Main Body Slot -->
<main class="container mx-auto px-6 py-8">
{{ $slot }}
</main>
</body>
</html>
Now, any view can consume this master layout by wrapping its content inside <x-layout>:
<x-layout title="User Dashboard - Veewom">
<x-slot:header>
<h1 class="text-2xl font-bold">Student & Developer Dashboard</h1>
</x-slot:header>
<div class="grid grid-cols-3 gap-6">
<x-card title="Active Classes" count="50" />
<x-card title="Completed Labs" count="15" />
<x-card title="Interview Score" count="98%" />
</div>
</x-layout>
Create an anonymous alert component in resources/views/components/alert.blade.php:
@props([
'type' => 'info',
'dismissible' => false
])
@php
$colorClasses = match($type) {
'success' => 'bg-green-100 text-green-800 border-green-300',
'danger' => '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 border rounded-md mb-4 {$colorClasses}"]) }} role="alert">
<div class="flex items-center justify-between">
<div>{{ $slot }}</div>
@if ($dismissible)
<button type="button" class="text-sm font-bold ml-4">×</button>
@endif
</div>
</div>
Consume it anywhere with custom HTML attributes merged automatically:
<x-alert type="danger" :dismissible="true" id="login-alert">
<strong>Security Alert:</strong> Please verify your email address.
</x-alert>
If you have data that must appear on every page (like category lists, user notifications, or shopping cart counts), do not query it in every controller. Register a View Composer in app/Providers/AppServiceProvider.php:
use Illuminate\Support\Facades\View;
use App\Models\Category;
public function boot(): void
{
// Share $globalCategories with every view that renders the sidebar
View::composer('partials.sidebar', function ($view) {
$view->with('globalCategories', Category::withCount('articles')->get());
});
}
Broaden your backend architecture, REST API design, and enterprise production engineering expertise:
Master loops, conditionals, and raw data escaping inside Blade templates.
Elevate Blade layouts with reactive full-stack Livewire components.
Inject compiled JavaScript modules and stylesheet links into Blade master layouts.
Build modular dashboard layouts and alert cards with component slots.