Laravel Blade Layouts: Mastering @extends, @section, and @yield
15 May 2025 | Category: Laravel
Blade layouts in Laravel provide a powerful way to create consistent, reusable templates for your application’s views. By using directives like @extends
, @section
, and @yield
, you can define a master layout and extend it in child views, ensuring a uniform structure across pages while allowing customization. This SEO-friendly, plagiarism-free guide explains Blade layouts, how to use @extends
, @section
, and @yield
, and best practices. Based on Laravel 11 (as of May 2025), this tutorial is tailored for beginners and intermediate developers.
What are Blade Layouts?
Blade layouts are master templates that define the common structure of your application’s views, such as headers, footers, navigation bars, and scripts. Child views extend these layouts, injecting specific content into predefined sections. The @extends
, @section
, and @yield
directives enable this modular approach, reducing code duplication and improving maintainability.
Key Benefits
- Consistency: Ensures a uniform look and feel across pages.
- Reusability: Defines shared elements (e.g., navigation) once.
- Maintainability: Centralizes updates to common UI elements.
- Flexibility: Allows child views to customize specific sections.
- Separation of Concerns: Keeps layout and content separate.
Core Blade Layout Directives
The three primary directives for Blade layouts are @extends
, @section
, and @yield
. Below, we explain each and how they work together.
1. @yield
The @yield
directive defines a placeholder in a layout where content from a child view will be injected. It’s typically used in the master layout to mark where sections will appear.
Syntax:
@yield('section-name')
@yield('section-name', 'default-content')
'section-name'
: The name of the section.'default-content'
: Optional fallback content if the section is not provided.
Example (in resources/views/layouts/app.blade.php
):
<!DOCTYPE html>
<html>
<head>
<title>@yield('title', 'My Laravel App')</title>
<link rel="stylesheet" href="/css/app.css">
</head>
<body>
<header>
<nav>
<a href="/">Home</a>
<a href="/posts">Posts</a>
</nav>
</header>
<main>
@yield('content')
</main>
<footer>
<p>© 2025 My Laravel App</p>
</footer>
</body>
</html>
@yield('title')
: Placeholder for the page title.@yield('content')
: Placeholder for the main content.
2. @extends
The @extends
directive is used in a child view to inherit a layout. It specifies which layout the view should use.
Syntax:
@extends('layout-name')
'layout-name'
: The path to the layout file (dot notation, relative toresources/views/
).
Example (in resources/views/posts/index.blade.php
):
@extends('layouts.app')
@section('title', 'Post List')
@section('content')
<h1>All Posts</h1>
<ul>
@foreach($posts as $post)
<li>{{ $post->title }}</li>
@endforeach
</ul>
@endsection
@extends('layouts.app')
: Inheritsresources/views/layouts/app.blade.php
.- The child view provides content for the
title
andcontent
sections.
3. @section
The @section
directive defines content for a specific section in a child view, which corresponds to a @yield
in the layout. It can also be used to define reusable sections within a view.
Syntax:
@section('section-name')
<!-- Content -->
@endsection
Or shorthand for single-line content:
@section('section-name', 'Content')
Example:
In the above posts/index.blade.php
:
@section('title', 'Post List')
: Sets the page title.@section('content') ... @endsection
: Defines the main content.
Combining Directives
The layout (layouts/app.blade.php
) uses @yield
to define placeholders, while the child view (posts/index.blade.php
) uses @extends
to inherit the layout and @section
to fill the placeholders.
Rendered Output:
<!DOCTYPE html>
<html>
<head>
<title>Post List</title>
<link rel="stylesheet" href="/css/app.css">
</head>
<body>
<header>
<nav>
<a href="/">Home</a>
<a href="/posts">Posts</a>
</nav>
</header>
<main>
<h1>All Posts</h1>
<ul>
<li>Post 1</li>
<li>Post 2</li>
</ul>
</main>
<footer>
<p>© 2025 My Laravel App</p>
</footer>
</body>
</html>
Advanced Layout Features
Appending to Sections
You can append content to a parent section using @parent
.
Layout (layouts/app.blade.php
):
<head>
@yield('scripts')
</head>
Child View:
@extends('layouts.app')
@section('scripts')
@parent
<script src="/extra.js"></script>
@endsection
@parent
: Includes the parent’s section content (if any) before appending the child’s content.
Reusing Sections
Define a section and reuse it elsewhere in the same view:
@section('sidebar')
<ul>
<li>Menu Item 1</li>
<li>Menu Item 2</li>
</ul>
@endsection
<div class="sidebar">
@show
</div>
@show
: Immediately renders the section and closes it.
Stacks
The @stack
and @push
directives manage collections of content, such as scripts or styles, often used for adding resources dynamically.
Layout:
<head>
@stack('styles')
</head>
<body>
@stack('scripts')
</body>
Child View:
@push('styles')
<link rel="stylesheet" href="/custom.css">
@endpush
@push('scripts')
<script src="/app.js"></script>
@endpush
@push
: Adds content to the named stack.@stack
: Renders all content pushed to the stack.
Including Sub-Views
Include partial views within a layout or child view:
<main>
@include('partials.header')
@yield('content')
</main>
@include('partials.header')
: Rendersresources/views/partials/header.blade.php
.
Conditional Include:
@includeIf('partials.header', ['title' => 'My Page'])
Only includes if the view exists.
Passing Data to Layouts
Pass data to layouts via the controller or view composer.
Controller:
public function index()
{
return view('posts.index', [
'posts' => Post::all(),
'appName' => 'My Laravel App'
]);
}
Layout:
<footer>
<p>© 2025 {{ $appName }}</p>
</footer>
Example: Real-World Layout
Below is a practical example of a layout and child view.
Layout (layouts/app.blade.php
)
<!DOCTYPE html>
<html>
<head>
<title>@yield('title', 'My Laravel App')</title>
<link rel="stylesheet" href="/css/app.css">
@stack('styles')
</head>
<body>
<header>
<nav>
<a href="{{ route('home') }}">Home</a>
<a href="{{ route('posts.index') }}">Posts</a>
</nav>
</header>
<main>
@yield('content')
</main>
<footer>
<p>© 2025 @yield('appName', 'My Laravel App')</p>
</footer>
<script src="/js/app.js"></script>
@stack('scripts')
</body>
</html>
Child View (posts/index.blade.php
)
@extends('layouts.app')
@section('title', 'Post List')
@push('styles')
<link rel="stylesheet" href="/css/posts.css">
@endpush
@section('content')
<h1>All Posts</h1>
@if($posts->isEmpty())
<p>No posts found.</p>
@else
<ul>
@foreach($posts as $post)
<li>
<a href="{{ route('posts.show', $post) }}">{{ $post->title }}</a>
</li>
@endforeach
</ul>
@endif
@endsection
@push('scripts')
<script src="/js/posts.js"></script>
@endpush
Controller
namespace App\Http\Controllers;
use App\Models\Post;
class PostController extends Controller
{
public function index()
{
return view('posts.index', [
'posts' => Post::all(),
'appName' => 'My Blog'
]);
}
}
Explanation
- Layout: Defines a reusable structure with
@yield
fortitle
,content
, andappName
, and@stack
forstyles
andscripts
. - Child View: Extends the layout, provides content for sections, and pushes additional styles and scripts.
- Controller: Passes data to the view, including posts and app name.
Best Practices for Blade Layouts
- Centralize Common Elements: Place headers, footers, and navigation in layouts.
- Use Meaningful Section Names: Choose clear names like
content
orsidebar
. - Leverage Stacks: Manage scripts and styles dynamically with
@stack
and@push
. - Keep Layouts Simple: Avoid complex logic in layouts; use controllers or components.
- Organize Layouts: Store layouts in
resources/views/layouts/
and partials inresources/views/partials/
. - Use Default Values: Provide fallback content with
@yield('name', 'default')
. - Secure Output: Use
{{ }}
for escaped output to prevent XSS. - Cache Views: Run
php artisan view:cache
in production for performance.
Debugging Layouts
If a layout isn’t rendering correctly:
- Check File Paths: Ensure
@extends('layouts.app')
points to the correct file. - Verify Sections: Confirm
@section
names match@yield
names. - Inspect Data: Use
{{ dd($variable) }}
to debug variables. - Clear Cache: Run
php artisan view:clear
if cached views cause issues. - Check Syntax: Ensure
@section
is closed with@endsection
.
Conclusion
Blade layouts, powered by @extends
, @section
, and @yield
, enable you to create consistent, reusable, and maintainable templates in Laravel. By defining a master layout and extending it in child views, you can streamline development, reduce duplication, and ensure a cohesive user experience. Features like @stack
, @parent
, and @include
add flexibility for dynamic content and complex UIs.
Next Steps:
- Create a layout in
resources/views/layouts/app.blade.php
. - Build a child view that extends the layout with custom sections.
- Experiment with
@stack
for scripts and styles.
For deeper insights, explore Laravel’s official documentation or connect with the Laravel community on platforms like X. Start building structured views with Blade layouts today!
Laravel Blade Layouts Example
This artifact provides a practical example of a Blade layout and a child view using @extends
, @section
, and @yield
.
Master Layout (layouts/app.blade.php
)
<!DOCTYPE html>
<html>
<head>
<title>@yield('title', 'My Laravel App')</title>
<link rel="stylesheet" href="/css/app.css">
@stack('styles')
</head>
<body>
<header>
<nav>
<a href="{{ route('home') }}">Home</a>
<a href="{{ route('posts.index') }}">Posts</a>
</nav>
</header>
<main>
@yield('content')
</main>
<footer>
<p>© 2025 @yield('appName', 'My Laravel App')</p>
</footer>
<script src="/js/app.js"></script>
@stack('scripts')
</body>
</html>
Child View (posts/index.blade.php
)
@extends('layouts.app')
@section('title', 'Post List')
@push('styles')
<link rel="stylesheet" href="/css/posts.css">
@endpush
@section('content')
<h1>All Posts</h1>
@if($posts->isEmpty())
<p>No posts found.</p>
@else
<ul>
@foreach($posts as $post)
<li>
<a href="{{ route('posts.show', $post) }}">{{ $post->title }}</a>
</li>
@endforeach
</ul>
@endif
@endsection
@push('scripts')
<script src="/js/posts.js"></script>
@endpush
Controller (PostController.php
)
namespace App\Http\Controllers;
use App\Models\Post;
class PostController extends Controller
{
public function index()
{
return view('posts.index', [
'posts' => Post::all(),
'appName' => 'My Blog'
]);
}
}
Routes (web.php
)
use App\Http\Controllers\PostController;
Route::get('/', fn() => view('welcome'))->name('home');
Route::resource('posts', PostController::class);
Usage
- Save the layout in
resources/views/layouts/app.blade.php
. - Save the child view in
resources/views/posts/index.blade.php
. - Ensure a
Post
model and migration exist. - Update
routes/web.php
with the provided routes. - Access
/posts
to see the rendered view.
This example demonstrates a reusable layout with dynamic title, content, styles, and scripts, extended by a child view that lists posts.