skip to content

Blade Views

Blade compiles templates into cached PHP with escaped echoes, control directives, components with slots, and layouts with stacks. Interviewers use it to test reuse and XSS-safe output.

on this pageshow

explore

questions

22

In Laravel Blade, what is the difference between a class-based component and an anonymous component, and when would you choose each?

level: juniorimportance: must knowfreq 62%

answer

  1. class plus view, or view alone
  2. app/View/Components vs resources/views/components
  3. constructor props vs @props
  4. make:component, --view for anonymous
  5. class earns its keep with logic or DI

basics

~20 s

A class-based component pairs a PHP class in app/View/Components with a view and takes props through its constructor; an anonymous component is just a Blade file in resources/views/components using @props. Pick a class for logic or injected services.

solid answer

~40 s

`php artisan make:component Alert` creates `app/View/Components/Alert.php` and `resources/views/components/alert.blade.php`; the class's constructor parameters are its props, public properties and methods become template variables, dependencies can be injected, and `shouldRender()` can suppress it. `php artisan make:component alert --view` creates only the Blade file; that **anonymous** component declares props and defaults with `@props` and has no PHP class. Both are rendered as `<x-alert>`, both get `$attributes` and `$slot`, and neither sees the parent view's variables. Use an anonymous component for presentational pieces such as an alert box; use a class when the component computes things, needs a service from the container, or should hide itself conditionally, like a modal that loads room availability.

code

php · 26 lines
php
<?php

namespace App\View\Components;

use App\Services\RoomAvailability;
use Illuminate\View\Component;
use Illuminate\View\View;

class AvailabilityModal extends Component
{
    public function __construct(
        public RoomAvailability $availability,
        public string $checkIn,
        public string $checkOut,
    ) {}

    public function freeRooms(): array
    {
        return $this->availability->between($this->checkIn, $this->checkOut);
    }

    public function render(): View
    {
        return view('components.availability-modal');
    }
}

go deeper

for a junior

Recall the two kinds, where their files live, make:component with --view, and that both render with an x- tag.

for a middle

Explain constructor props versus @props, kebab-to-camel mapping, public methods as variables, and that components are isolated from parent variables.

for a senior

Decide when logic, injected services or shouldRender justify a class, and guard runtime component selection with an allow-list.

for a principal

Set a component-library convention - anonymous by default, classes for behaviour - so a growing UI stays consistent and reviewable.

## What a Blade component is A **Blade component** is a reusable piece of UI rendered with an HTML-like tag: `<x-alert type="warning">Room 204 is overbooked</x-alert>`. It receives **props** (declared inputs), an **attribute bag** of any extra HTML attributes, and **slots** of inner content. Unlike an `@include`, a component does **not** see the parent view's variables; everything it uses must be passed in or shared globally. Laravel offers two ways to define one. ## Class-based components ```bash php artisan make:component Alert ``` creates two files: - `app/View/Components/Alert.php` - a class extending `Illuminate\View\Component`. - `resources/views/components/alert.blade.php` - its template, returned from `render()`. The class gives you: 1. **Constructor props.** `public function __construct(public string $type, public string $message)` - attribute `type="error"` maps to `$type`; kebab-case attributes map to camelCase parameters (`alert-type` to `$alertType`). 2. **Public properties and methods as template variables.** A public method `isSelected($option)` is callable in the view as `$isSelected($option)`. 3. **Dependency injection.** Services listed before the data parameters are resolved from the container. 4. **`shouldRender()`**, which can return `false` to render nothing - for instance, an alert that hides itself when there is no message. 5. **`$except`**, a protected array listing public members that should not become template variables. `--inline` puts the markup in `render()` as a string instead of a separate view file, and `--test`, `--pest` or `--phpunit` also generate a test. ## Anonymous components ```bash php artisan make:component alert --view ``` creates only `resources/views/components/alert.blade.php`. There is no class; the template declares its props: ```html @props(['type' => 'info', 'dismissible' => false]) <div {{ $attributes->merge(['class' => 'alert alert-'.$type]) }}>{{ $slot }}</div> ``` Attributes named in `@props` become variables (with the array values as defaults); everything else stays in `$attributes`. Nested paths use dots (`<x-modal.footer>` for `components/modal/footer.blade.php`), and a directory can hold its own root template (`components/modal/modal.blade.php` or `index.blade.php`) rendered as `<x-modal>`. ## Where Blade finds components Components are discovered automatically: `<x-alert>` resolves to the class `App\View\Components\Alert` if it exists, otherwise to the view `resources/views/components/alert.blade.php`. Dots map to sub-directories on both sides (`<x-forms.input>`). Packages and modular apps can add more anonymous locations with `Blade::anonymousComponentPath($path, $prefix)` in a provider's `boot()`, rendered as `<x-prefix::panel>` when a prefix is given. Names such as `data`, `render`, `resolve`, `view`, `shouldRender` and `withAttributes` are reserved and cannot be public properties or methods on a component class. ## Comparing them | | Class-based | Anonymous | |---|---|---| | Files | class + view (or inline) | one Blade file | | Props declared in | constructor | `@props` | | Logic | methods, computed properties | only what fits in the template | | Container services | constructor injection | none | | Suppress rendering | `shouldRender()` | wrap the markup in `@if` | | Typical use | modals with data, form controls with rules | alerts, badges, cards, buttons | ## Choosing for a hotel-admin UI - The **alert** (success, warning, danger) is pure presentation: an anonymous component with `@props(['type' => 'info'])` is enough. - The **confirm modal** is mostly markup with slots: anonymous works too. - A **room-availability modal** that asks a booking service for free rooms and formats dates is a class component: the constructor injects the service, a public method formats dates, and the template stays readable. A useful rule: start anonymous; promote to a class when the template grows PHP logic, or the component needs the container. ## Picking a component at runtime When the component name is only known at runtime - an alert whose style comes from a notification record - `<x-dynamic-component :component="'alerts.'.$notice->level" class="mt-2" />` renders the named component and forwards the remaining attributes. Keep the name to a known list; letting request data choose a component name lets a visitor render any component. ## Component or include? Includes are still fine for fragments that deliberately share the parent's context. A component wins when the piece has a clear interface - declared props, caller-supplied classes merged into the root element, named content areas - because that interface is visible at the call site and enforced by the component itself.

  • Can a Blade component read variables defined in the view that renders it?
    No. Unlike `@include`, a component renders with only its props, attribute bag, slots and globally shared view data. A variable in the parent must be passed explicitly, for example `:guest="$guest"`. That isolation is what makes a component's interface visible at the call site.
  • When would shouldRender() be the right tool?
    When the component itself knows it has nothing to show - an alert with an empty message, a banner outside its date range. Returning `false` from `shouldRender()` makes the tag render nothing, so call sites need no surrounding `@if`. Anonymous components have no class, so they must wrap their markup in a conditional instead.
  • Why keep the name passed to x-dynamic-component to a known list?
    `x-dynamic-component` renders whatever component name it is given. If that name comes from request data, a visitor can render any component the app has, including admin-only fragments. Map the incoming value to an allow-list of component names first.

saying these in an interview costs you the question

  • Anonymous components cannot receive props
  • Components inherit the parent view's variables like @include
  • Every component needs a PHP class in app/View/Components
  • Constructor parameters must be written in kebab-case
  • Class components are always faster, so anonymous ones should be avoided
open as a page

Inside a Blade @foreach, what does $loop provide, and how would you use it to mark a pricing table's first, last and alternating rows?

level: juniorimportance: must knowfreq 62%

basics

~10 s

Blade sets a $loop object on every @foreach iteration with index (from 0), iteration (from 1), count, remaining, first, last, odd, even, depth and parent, so rows can be styled without a hand-kept counter.

open as a page

In a Blade view, what is the difference between {{ $value }} and {!! $value !!}, and when is the raw form acceptable?

level: juniorimportance: must knowfreq 82%

basics

~20 s

Blade compiles {{ $value }} to an echo through the e() helper, which runs htmlspecialchars so markup prints as text; {!! $value !!} echoes the value untouched, so it is safe only for HTML your own code built or sanitized.

open as a page

In Laravel Blade, how does a layout component with {{ $slot }} differ from an @extends layout, and which suits a new app?

level: juniorimportance: must knowfreq 68%

basics

~20 s

A layout component wraps the page: markup between <x-layout> tags lands in the component's {{ $slot }}. An @extends layout is inheritance: the child fills @section blocks that the layout prints with @yield. New apps usually choose components.

open as a page

In a Blade component, how does $attributes->merge() treat class compared with other attributes, and when do you need class() or prepends()?

level: middleimportance: must knowfreq 55%

basics

~20 s

merge() adds default attributes: class and style defaults are joined with the caller's values, while any other default is replaced by the caller's value. class() adds classes conditionally; prepends() makes a non-class default join instead.

open as a page

In Blade, how do @push, @prepend, @stack and @pushOnce let each university course page add its own scripts to a shared layout?

level: middleimportance: must knowfreq 48%

basics

~20 s

A page or component adds markup to a named stack with @push('scripts'), and the layout prints everything collected with @stack('scripts'). @prepend puts content ahead of pushed content, and @pushOnce adds a block only once per render.

open as a page

In a Blade view, when should you use @forelse instead of @foreach, and why does @empty mean two different things?

level: juniorimportance: should knowfreq 48%

basics

~20 s

@forelse loops like @foreach but renders its @empty branch when the list has no items. A standalone @empty($x) ... @endempty is a different directive that wraps PHP's empty(), which is false for any object, even an empty Collection.

open as a page

In a Blade view that also contains Vue-style templates, how do @{{ }} and @verbatim stop Blade from compiling the client-side curly braces?

level: juniorimportance: should knowfreq 42%

basics

~20 s

Prefixing an echo with @, as in @{{ name }}, makes Blade drop the @ and leave {{ name }} for the JavaScript framework. Wrapping a region in @verbatim ... @endverbatim leaves everything inside uncompiled, echoes and directives alike.

open as a page

In Laravel, what does Blade compile a .blade.php template into, where is the result stored, and when is it recompiled?

level: juniorimportance: should knowfreq 36%

basics

~20 s

Blade compiles each template into a plain PHP file stored in storage/framework/views (config key view.compiled, env VIEW_COMPILED_PATH). On render Laravel reuses it unless it is missing or the source file's modification time is not older than the compiled file's.

open as a page

In a Blade modal component, how do the default $slot and named slots such as <x-slot:footer> work, including optional slots and slot attributes?

level: middleimportance: should knowfreq 45%

basics

~20 s

Content between a component's tags that is not inside an x-slot becomes $slot; each x-slot:name becomes a $name variable. Slots are ComponentSlot objects with isEmpty(), hasActualContent() and their own attributes bag, and an optional slot needs a default.

open as a page

When passing data to a Blade component, what is the difference between type="error", :message="$message" and ::class, and how does @props decide what is a prop?

level: middleimportance: should knowfreq 48%

basics

~20 s

A plain attribute passes a string, a colon attribute passes a PHP expression's value, and a double colon emits a single-colon attribute for JavaScript. Names in @props or the constructor become variables; the rest stay in $attributes.

open as a page

In a Blade view, what do @class, @style, @checked and @selected compile to, and what hand-written template code do they replace?

level: middleimportance: should knowfreq 42%

basics

~20 s

@class and @style take an array of always-on entries plus entry => condition pairs and write a complete class or style attribute; @checked, @selected, @disabled, @readonly and @required print the bare attribute when their condition is true.

open as a page

In Blade, how do @include, @includeIf, @includeWhen, @includeFirst, @includeIsolated and @each differ, especially in which variables the included view can see?

level: middleimportance: should knowfreq 50%

basics

~20 s

@include and its If, When, Unless and First variants hand the partial every parent variable plus extras, differing only in when they render; @includeIsolated passes just the given array, and @each renders a view per item with only that item and its key.

open as a page

In a Laravel Blade view, how should you hand a PHP array or string to an inline script, and what goes wrong with {{ json_encode($data) }}?

level: middleimportance: should knowfreq 45%

basics

~10 s

Use Js::from($data) or the @js directive: they emit a JavaScript expression with <, >, &, and quotes hex-escaped. {{ json_encode() }} fails because e() turns quotes into ", which a script block never decodes.

open as a page

In a Blade @extends layout, how do @section, @parent, @show, @endsection and @yield decide whether a child replaces or extends layout content?

level: middleimportance: should knowfreq 38%

basics

~20 s

The child renders first, so its section is stored first and wins. A layout default written as @section ... @show only survives where the child wrote @parent, which is a placeholder for it. @endsection only stores; @show and @yield print.

open as a page

On a Laravel pricing page, how would you add a @plan('pro') conditional with Blade::if, and why is it safer than Blade::directive for a per-visitor check?

level: seniorimportance: should knowfreq 30%

basics

~20 s

Blade::if('plan', fn (string $plan) => ...) registers @plan, @elseplan, @unlessplan and @endplan that call your closure through Blade::check() each render; a Blade::directive handler runs once at compile time, so per-visitor logic inside it gets frozen into the cached view.

open as a page

In a Blade view, {{ }} encodes quotes, so why can an href, an unquoted attribute or an onclick handler built from user data still be an XSS hole?

level: seniorimportance: should knowfreq 40%

basics

~20 s

e() only stops a value breaking out of quoted HTML. Unquoted attributes break on a space, a javascript: URL has nothing to encode, and an onclick attribute is entity-decoded before its JavaScript runs, so each needs quoting, a scheme check or Js::from.

open as a page

On a Laravel community forum that allows lightly formatted user bios, why can wrapping a bio in HtmlString be as dangerous as {!! !!} even when the view uses {{ }}?

level: seniorimportance: should knowfreq 34%

basics

~20 s

Blade's e() helper returns any Htmlable object's toHtml() without escaping, and HtmlString is Htmlable, so a bio wrapped in one renders as live markup inside {{ }}; the wrapper must only ever hold HTML your code has sanitized.

open as a page

In Laravel, when would you use View::share, a view composer or a view creator to give every university page its department navigation?

level: seniorimportance: should knowfreq 45%

basics

~20 s

View::share sets a value once, in a provider's boot(), for every view. A view composer runs just before a named view renders, so it suits data that only some pages need. A creator runs when the view is created, before render.

open as a page

In a Laravel Blade view, why does a value stored as Tom &amp; Jerry show a literal &amp; to visitors, and what does Blade::withoutDoubleEncoding() change?

level: middleimportance: nice to knowfreq 22%

basics

~20 s

Blade's e() double-encodes by default, so an entity already in the data becomes &amp; and shows as &. Blade::withoutDoubleEncoding() compiles {{ }} to e($x, false), leaving existing entities intact while still escaping < and >.

open as a page

In Laravel, how do Blade's @fragment directive and a view's fragmentIf() method return only a course list for a partial-page request?

level: middleimportance: nice to knowfreq 20%

basics

~10 s

Wrap the list in @fragment('course-list') ... @endfragment. Returning view(...)->fragment('course-list') renders the template but sends only that block, and fragmentIf($condition, 'course-list') does so only when the condition holds, otherwise the full page.

open as a page

In nested Blade components such as <x-modal size="lg"> containing <x-modal.footer>, how does @aware let the child read the parent's props, and why can it miss the parent's defaults?

level: seniorimportance: nice to knowfreq 22%

basics

~20 s

@aware(['size' => 'md']) lets a child read size from the data of its enclosing components. For an anonymous parent that data is only what the caller wrote on the tag, not @props defaults, so the child needs a matching default.

open as a page