Blade templates and components

Laravel · Essentials · 12 min

Blade is how server-rendered Laravel apps produce their pages, safely and with reusable components.

Blade templates live in resources/views with the .blade.php extension. view('posts.show', [...]) renders resources/views/posts/show.blade.php. Templates compile to plain PHP and are cached.

Output:

  • {{ $post->title }} echoes escaped output via htmlspecialchars, safe against XSS.
  • {!! $html !!} echoes raw HTML; use it only for content you trust.

Directives wrap PHP control structures: @if/@elseif/@else/@endif, @unless, @isset, @foreach, and @forelse ... @empty ... @endforelse for lists that may be empty. Inside loops, $loop->first, $loop->last and $loop->iteration are available. @auth/@guest check login status; @can('update', $post) checks authorization.

Reuse markup with components. An anonymous component is just a view in resources/views/components, used as an HTML-like tag:

<x-layout title="Posts">
    <h1>All posts</h1>
</x-layout>

Inside components/layout.blade.php, {{ $slot }} prints the content and $title the attribute. Named slots use <x-slot:footer>. Class-based components (php artisan make:component Alert) add PHP logic.

Forms need @csrf, which adds the hidden token Laravel checks on every POST, and @method('PUT') to spoof PUT, PATCH or DELETE. Show validation errors with @error('title') {{ $message }} @enderror and refill fields with old('title').

Example

{{-- resources/views/components/layout.blade.php --}}
<html>
<head><title>{{ $title ?? 'My App' }}</title></head>
<body>
    @if (session('status'))
        <p class="flash">{{ session('status') }}</p>
    @endif
    {{ $slot }}
</body>
</html>
{{-- resources/views/posts/edit.blade.php --}}
<x-layout title="Edit post">
    <form method="POST" action="{{ route('posts.update', $post) }}">
        @csrf
        @method('PUT')
        <input name="title" value="{{ old('title', $post->title) }}">
        @error('title') <span class="error">{{ $message }}</span> @enderror
        <button>Save</button>
    </form>
    @forelse ($post->comments as $comment)
        <p>{{ $loop->iteration }}. {{ $comment->body }}</p>
    @empty
        <p>No comments yet.</p>
    @endforelse
</x-layout>

Remember

  • {{ }} escapes output; {!! !!} doesn't, so use it rarely
  • Components (<x-name>) with $slot replace copy-pasted layouts
  • Every form needs @csrf; use @method for PUT/PATCH/DELETE

Watch out for

  • Rendering user content with {!! !!}, which opens an XSS hole.

Check yourself

  1. A POST form in a Blade view returns HTTP 419. What is most likely missing?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: laravel.com/docs/12.x/blade