Laravel Blade Layouts: Mastering @extends, @section, and @yield
6 July 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
titleandcontentsections.
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
@yieldfortitle,content, andappName, and@stackforstylesandscripts. - 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
contentorsidebar. - Leverage Stacks: Manage scripts and styles dynamically with
@stackand@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:cachein 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
@sectionnames match@yieldnames. - Inspect Data: Use
{{ dd($variable) }}to debug variables. - Clear Cache: Run
php artisan view:clearif cached views cause issues. - Check Syntax: Ensure
@sectionis 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
@stackfor 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
Postmodel and migration exist. - Update
routes/web.phpwith the provided routes. - Access
/poststo 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.