Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

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 Alert

The 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.

Thanks for reading!

Donate to the site — we work hard for you.