Blade — Laravel's template engine and what the name means
Concept
Blade — Laravel's template engine for rendering HTML views. The name is a play on the "sharp" PHP alternative to raw <?php ?> tags — it "cuts through" boilerplate syntax.
What Blade provides over plain PHP:
- Cleaner syntax:
{{ $variable }}instead of<?php echo htmlspecialchars($variable) ?>. - Template inheritance:
@extends('layout')+@section()+@yield()for master layouts. - Components:
<x-alert type="error">{{ $message }}</x-alert>— reusable HTML components. - Control flow directives:
@if,@foreach,@forelse,@switch,@unless,@empty. - Includes:
@include('partial'),@includeWhen($condition, 'partial'). - CSRF:
@csrfinserts the hidden CSRF token field. - Stack:
@stack('scripts')+@push('scripts')— inject content from child templates into named stacks.
Security by default: {{ $variable }} escapes HTML (htmlspecialchars). Use {!! $variable !!} only for intentionally unescaped HTML (trusted sources only — never user input).
Compilation: Blade templates are compiled to plain PHP and cached in storage/framework/views/. The compiled file is just PHP with echo statements. Recompiles when the template changes.
Livewire integration: Livewire is built on Blade. Livewire components are Blade templates with PHP logic that re-render reactively via Ajax.
When NOT to use Blade: If your frontend is a SPA (Vue, React, Next.js), Blade is irrelevant. Your backend returns JSON from API endpoints instead. Blade is for server-rendered HTML.
Code Example
{{-- resources/views/layouts/app.blade.php --}}
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<title>@yield('title', 'My App')</title>
@stack('styles')
</head>
<body>
@include('partials.nav') {{-- include a partial --}}
<main>
@yield('content') {{-- child views inject here --}}
</main>
@stack('scripts')
</body>
</html>{{-- resources/views/users/index.blade.php --}}
@extends('layouts.app')
@section('title', 'Users')
@section('content')
<h1>Users</h1>
@csrf {{-- generates <input type="hidden" name="_token" value="..."> --}}
{{-- Escaped output — safe from XSS --}}
<p>Welcome, {{ $user->name }}</p>
{{-- equivalent to: <?php echo htmlspecialchars($user->name) ?> --}}
{{-- Unescaped — ONLY for trusted HTML --}}
<p>{!! $article->rendered_html !!}</p>
{{-- Control flow --}}
@if ($users->isEmpty())
<p>No users found.</p>
@else
@foreach ($users as $user)
<div>{{ $user->name }}</div>
@endforeach
@endif
{{-- @forelse — combines foreach with empty check --}}
@forelse ($users as $user)
<div>{{ $user->name }}</div>
@empty
<p>No users found.</p>
@endforelse
@endsection
@push('scripts')
<script>console.log('Users page loaded');</script>
@endpush{{-- resources/views/components/alert.blade.php (Blade component) --}}
@props(['type' => 'info', 'message'])
<div class="alert alert-{{ $type }}">
{{ $message }}
</div>{{-- Using the component --}}
<x-alert type="error" message="Something went wrong" />
<x-alert type="success">{{ __('Saved successfully') }}</x-alert>