Laravel Tutorial · Laravel Basics · Lesson 6 of 27

Blade Templates

Render HTML with Blade: echo values safely, use @if, @foreach and @forelse, build layouts with components and slots.

Create a free account to save this page, take notes and track your progress. Sign in

Blade basics

Blade is Laravel's template engine. Templates live in resources/views as *.blade.php files and are returned from routes with view('posts.index', ['posts' => $posts]).

  • {{ $value }} echoes a value HTML-escaped, protecting against XSS.
  • {!! $html !!} echoes raw HTML: only for content you trust.
  • @if, @elseif, @else, @unless, @isset, @empty.
  • @foreach, @forelse ... @empty ... @endforelse (with a built-in $loop variable), @for, @while.
  • @csrf in forms adds the CSRF token field; @method('PUT') fakes PUT/DELETE in HTML forms.
Escaping, conditionals and loops
<?php
use Illuminate\Support\Facades\Blade;

$template = <<<'BLADE'
<h1>{{ $title }}</h1>
@forelse ($posts as $post)
<p>{{ $loop->iteration }}. {{ $post['title'] }}@if ($post['draft']) (draft)@endif</p>
@empty
<p>No posts yet.</p>
@endforelse
<p>Comment: {{ $comment }}</p>
BLADE;

echo Blade::render($template, [
    'title' => 'My Blog',
    'posts' => [['title' => 'Hello Blade', 'draft' => false], ['title' => 'Routing tips', 'draft' => true]],
    'comment' => '<script>alert("hi")</script>',   // escaped automatically
]), "\n---\n";
echo Blade::render($template, ['title' => 'Empty Blog', 'posts' => [], 'comment' => 'none']);

Output

<h1>My Blog</h1>
<p>1. Hello Blade</p>
<p>2. Routing tips (draft)</p>
<p>Comment: &lt;script&gt;alert(&quot;hi&quot;)&lt;/script&gt;</p>
---
<h1>Empty Blog</h1>
<p>No posts yet.</p>
<p>Comment: none</p>

Run this on your computer — see “Get Started” for setup.

Layouts and components

Shared page structure goes in components: resources/views/components/layout.blade.php used as <x-layout title="Blog">...</x-layout>. Inside the component, {{ $slot }} is the content between the tags, @props declares attributes with defaults, and named slots fill other areas of a layout:

<x-layout title="Blog">
    <x-slot:sidebar>Recent posts…</x-slot>
    Main content here.
</x-layout>

Anonymous components are just Blade files; class components (php artisan make:component) add PHP logic.

A reusable component with props and a slot
<?php
use Illuminate\Support\Facades\Blade;
use Illuminate\Support\Facades\File;

// An anonymous component: just a Blade file in resources/views/components.
File::ensureDirectoryExists(resource_path('views/components'));
File::put(resource_path('views/components/alert.blade.php'), <<<'BLADE'
@props(['type' => 'info', 'title' => null])
<div class="alert alert-{{ $type }}">@if ($title)<strong>{{ $title }}</strong> @endif{{ $slot }}</div>
BLADE);

echo Blade::render('<x-alert>Profile saved.</x-alert>'), "\n";
echo Blade::render('<x-alert type="error" title="Oops!">Payment failed.</x-alert>'), "\n";

File::delete(resource_path('views/components/alert.blade.php'));

Output

<div class="alert alert-info">Profile saved.</div>
<div class="alert alert-error"><strong>Oops!</strong> Payment failed.</div>

Run this on your computer — see “Get Started” for setup.

Test yourself

Which Blade syntax escapes HTML in the output?

  1. {!! $value !!}
  2. {{ $value }}
  3. @echo($value)
  4. <?= $value ?>
Show answer

Answer: {{ $value }}

Was this page helpful?