All rules

Sheath rule

blade-require-props

Anonymous Blade components should declare @props.
Package
Core
Category
Blade
Default severity
info by default
Auto-fix
Manual fix

#Enabling the Rule

Enable this rule to require every anonymous component to declare @props:

<?php
'rules' => [
'blade-require-props' => 'warning',
],

#Why

@props is what separates a component's own inputs from the attributes meant for its root element. A prop it does not declare stays in $attributes, so {{ $attributes }} renders it onto the markup as a stray HTML attribute.

It also gives the file a signature: the list of what the component takes, and its defaults, without reading the body.

#Examples

This requirement applies only to files in component directories such as resources/views/components/.

#Without @props (flagged)

<!-- resources/views/components/alert.blade.php -->
<!-- Missing @props - what attributes does this expect? -->
<div class="alert alert-{{ $type }}">
{{ $message }}
</div>

#With @props (correct)

<!-- resources/views/components/alert.blade.php -->
@props([
'type' => 'info',
'message',
])
<div class="alert alert-{{ $type }}">
{{ $message }}
</div>

#More Examples

<!-- resources/views/components/button.blade.php -->
@props([
'variant' => 'primary',
'disabled' => false,
])
<button
class="btn btn-{{ $variant }}"
{{ $disabled ? 'disabled' : '' }}
{{ $attributes }}
>
{{ $slot }}
</button>
<!-- resources/views/components/card.blade.php -->
@props([
'title',
'footer' => null,
])
<div {{ $attributes->merge(['class' => 'card']) }}>
<h3>{{ $title }}</h3>
<div>{{ $slot }}</div>
@if($footer)
<footer>{{ $footer }}</footer>
@endif
</div>

#@props Syntax

<!-- With default values -->
@props([
'type' => 'info', // Optional with default
'size' => 'md',
])
<!-- Required props (no default) -->
@props([
'title', // Required
'id', // Required
])
<!-- Mixed -->
@props([
'title', // Required
'subtitle' => null, // Optional
'icon' => 'default', // Optional with default
])

#$attributes Behavior

Without @props:

<!-- All passed attributes go to $attributes -->
<div {{ $attributes }}> <!-- Includes type, message, class, etc. -->

With @props:

@props(['type', 'message'])
<!-- Only non-prop attributes go to $attributes -->
<div {{ $attributes }}> <!-- Only class, id, etc. - not type/message -->

#Options

Use this option to define which view paths contain Blade components.

Option Type Default Description
componentPaths array ['components/', 'Components/', '/components/', '/Components/'] Directory paths that mark a file as a component
<?php
'blade-require-props' => ['warning', [
'componentPaths' => ['components/', 'partials/components/'],
]],

#Notes

  • Only files in component directories are checked
  • Component paths match complete directory boundaries, so components-old and notcomponents do not match the default components/ directory
  • Class-based components define props in the PHP class instead. Conventionally discovered App\\View\\Components classes are recognized during standalone programmatic linting as well as inside a booted Laravel application.
  • @props should be at the top of the component file

#Related Rules