Laravel

Laravel is a powerful and popular PHP framework that simplifies and accelerates web application development. Its elegant syntax, robust features like Eloquent ORM, Blade templating, and built-in security tools help developers create efficient and scalable apps. With strong community support and extensive documentation, Laravel is an ideal choice for both novice and experienced developers

Laravel Blade Layouts: Mastering @extends, @section, and @yield

15 May 2025 | Category:

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>&copy; 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 to resources/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'): Inherits resources/views/layouts/app.blade.php.
  • The child view provides content for the title and content 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>&copy; 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'): Renders resources/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>&copy; 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>&copy; 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 for title, content, and appName, and @stack for styles and scripts.
  • 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

  1. Centralize Common Elements: Place headers, footers, and navigation in layouts.
  2. Use Meaningful Section Names: Choose clear names like content or sidebar.
  3. Leverage Stacks: Manage scripts and styles dynamically with @stack and @push.
  4. Keep Layouts Simple: Avoid complex logic in layouts; use controllers or components.
  5. Organize Layouts: Store layouts in resources/views/layouts/ and partials in resources/views/partials/.
  6. Use Default Values: Provide fallback content with @yield('name', 'default').
  7. Secure Output: Use {{ }} for escaped output to prevent XSS.
  8. 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>&copy; 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

  1. Save the layout in resources/views/layouts/app.blade.php.
  2. Save the child view in resources/views/posts/index.blade.php.
  3. Ensure a Post model and migration exist.
  4. Update routes/web.php with the provided routes.
  5. 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.