Blade components
A button, a card, an error message appear on a site dozens of times. A Blade component turns such a fragment into a tag of its own: the markup is described in one place and used everywhere.
Creating a component
A simple component needs just a template in the resources/views/components folder:
{{-- resources/views/components/alert.blade.php --}}
<div class="alert">
{{ $slot }}
</div>The $slot variable is whatever is written between the opening and closing tags of the component.
Using it
A component tag starts with x-:
<x-alert>
The post was saved.
</x-alert>A component in a subfolder is called with a dot: the file components/forms/input.blade.php is <x-forms.input />.
Attributes
Values are passed as attributes. The component's template declares them with the @props directive — which also sets the defaults:
{{-- resources/views/components/alert.blade.php --}}
@props(['type' => 'info', 'title'])
<div class="alert alert-{{ $type }}">
<strong>{{ $title }}</strong>
{{ $slot }}
</div><x-alert type="error" title="Error">
Could not save.
</x-alert>
<x-alert :title="$message" />A colon before the attribute name means the value is a PHP expression, not a string.
The other attributes
Attributes missing from @props go into the $attributes variable. This is how a class or an id can be passed to a component:
{{-- resources/views/components/button.blade.php --}}
<button {{ $attributes->merge(['class' => 'btn', 'type' => 'button']) }}>
{{ $slot }}
</button><x-button class="btn-primary" type="submit">Save</x-button>The classes are merged: the result is class="btn btn-primary".
Named slots
When a component needs several areas, use named slots:
{{-- resources/views/components/card.blade.php --}}
<div class="card">
<div class="card-header">{{ $header }}</div>
<div class="card-body">{{ $slot }}</div>
</div><x-card>
<x-slot:header>Heading</x-slot:header>
The content of the card.
</x-card>A layout from components
A component can replace a layout with @extends:
{{-- resources/views/components/layout.blade.php --}}
<html>
<head>
<title>{{ $title ?? 'My blog' }}</title>
</head>
<body>
<main>{{ $slot }}</main>
</body>
</html><x-layout>
<x-slot:title>Posts</x-slot:title>
<h1>Posts</h1>
</x-layout>A component with a class
If a component needs logic, create it with a command — a class and a template appear:
php artisan make:component AlertThe public properties of the class are available in the template as variables.
Common mistake
Without a colon an attribute value is always a string. <x-alert title="$message" /> passes the literal text $message, and <x-post post="$post" /> passes a string instead of an object. Put a colon before variables and expressions.