Sheath rule
blade-component-tag-integrity
<x-*> or <x:*> tag
must be paired or self-closed.
for echoes in bound attributes. See Auto-fix.
#Why
Blade component tags accept plain attributes, bound attributes, @class(...),
@style(...), the :$var shorthand, and $attributes method chains such as
{{ $attributes->whereStartsWith('wire:model') }}. The following unsupported
forms break compilation or prevent Blade from recognizing the component.
- An echo in a bound attribute:
:message="{{ $msg }}". Bound values are already PHP expressions, so use:message="$msg"instead. - A directive in the attribute list:
@if($x) type="a" @endif, or even the boolean helpers (@checked($v),@disabled($v)) that are documented for plain HTML elements. These directives prevent Blade from recognizing the tag as a component. - Any echo other than
{{ $attributes... }}in attribute position. Other echoes also prevent the tag from being recognized as a component. - An
<x-*>opener that never closes, or a</x-*>closer with no opener. Unclosed component tags can discard output, while stray closing tags produce an invalid component close.
All checks are limited to Laravel's x- and x: tags. Other prefixes (livewire:, flux:)
compile through their own packages, whose rules differ.
#Examples
#Bad
<x-alert :message="{{ $msg }}" />
<x-alert @if($urgent) type="error" @endif />
<x-input @checked($value) />
<x-alert {{ $foo }} />
<x-alert>
<p>This opener is never closed; everything after it is lost.</p>
<p>Done.</p>
</x-alert>
#Good
<x-alert :message="$msg" />
<x-alert :type="$urgent ? 'error' : null" />
<x-input :checked="$value" />
<x-button @class(['p-4', 'font-bold' => $active]) @style(['color: red' => $hasError]) />
<x-alert {{ $attributes->merge(['class' => 'alert']) }} />
<x-input {{ $attributes->whereStartsWith('wire:model') }} />
<x-alert>
<p>Content</p>
</x-alert>
<input type="checkbox" @checked($value) />
#Auto-fix
When a bound attribute's value is exactly one echo and nothing else, auto-fix unwraps it while preserving the intended value:
{{-- before --}}
<x-alert :message="{{ $msg }}" />
{{-- after --}}
<x-alert :message="$msg" />
A bound value that mixes an echo with other text gets no fix because the intended expression cannot be inferred.
The other findings have no fix. Moving a directive out of a tag or pairing an unclosed tag requires a structural decision.
#Notes
- The boolean helpers (
@checked,@disabled,@selected,@readonly,@required) are documented for plain HTML elements and keep working there; it is only inside<x-*>tags that they break the tag. Bind the attribute (:checked="$value") instead. Component attribute bags render boolean attributes correctly from bound values. - Listener-shaped attributes such as
@error="handler"can collide with Blade directive names. See blade-no-directive-attribute-collision.
#Related Rules
- blade-no-directive-attribute-collision - event-listener attributes that collide with directive names
- blade-component-self-closing - prefer self-closing syntax for empty components
- blade-no-unquoted-echo-attribute - unquoted attribute values containing echoes