Component classes let you run PHP logic before a component renders. You define a class with a mount() method, Lex calls it with the component’s props, and all public properties on the class instance are then available as variables inside the component template.
How class mounting works
- Lex resolves the component class for the tag (by explicit registration or auto-discovery).
- It instantiates the class.
- It calls
mount(), injecting props by parameter name using reflection. Parameters with default values are used when the matching prop is absent.
- All public properties of the class instance are merged into the template scope alongside the passed props.
Public class properties are merged after the raw props. If a class property and a prop share the same name, the class property wins.
Writing a component class
Create a class with a mount() method. Declare public properties for any values you want to expose to the template:
app/View/Components/AlertComponent.php
namespace App\View\Components;
final class AlertComponent
{
public string $icon = '';
public string $classes = '';
public function mount(string $type = 'info', bool $dismissible = false): void
{
$this->icon = match ($type) {
'success' => '✓',
'error' => '✖',
default => 'ℹ',
};
$this->classes = "alert alert-{$type}"
. ($dismissible ? ' alert-dismissible' : '');
}
}
The corresponding template can access both the original props ($type, $dismissible) and the class’s public properties ($icon, $classes):
views/components/alert.lex
<!-- Props: $type, $dismissible | Class properties: $icon, $classes -->
<div class="{{ $classes }}">
<span>{{ $icon }}</span>
{!! $slot !!}
#if ($dismissible)
<button class="close">×</button>
#endif
</div>
Usage in a parent template:
<Alert type="success" dismissible />
Setting the class namespace
Call componentClassNamespace() with the base namespace where your component classes live. Lex uses this namespace for auto-discovery:
$lexer->componentClassNamespace('App\\View\\Components');
This is typically called once in your application bootstrap alongside other Lexer configuration.
Auto-discovery convention
When a namespace is set, Lex builds the class name from the component tag by normalizing it to PascalCase and appending Component:
| Tag | Class resolved |
|---|
<Alert /> | App\View\Components\AlertComponent |
<alert /> | App\View\Components\AlertComponent |
<card-name /> | App\View\Components\CardNameComponent |
<UserProfile /> | App\View\Components\UserProfileComponent |
The Component suffix is required. A class named App\View\Components\Alert will not be found by auto-discovery — only App\View\Components\AlertComponent will. This prevents accidental collisions with non-component classes in the same namespace.
If no matching class exists for a component, Lex renders the component normally from props alone — no error is thrown.
Explicit class registration
To register a component class by name instead of relying on auto-discovery:
$lexer->registerComponentClass('Alert', App\View\Components\AlertComponent::class);
Explicit registration takes priority over namespace-based auto-discovery.
Prop injection rules
Lex uses ReflectionMethod to inspect mount() and injects props by parameter name:
- If the component was passed a prop whose name matches a
mount() parameter, that value is used.
- If no matching prop was passed but the parameter has a default value, the default is used.
- Parameters with no matching prop and no default are not passed — PHP’s own default handling applies.
Full example
Create the component class
app/View/Components/AlertComponent.php
namespace App\View\Components;
final class AlertComponent
{
public string $icon = '';
public string $classes = '';
public function mount(string $type = 'info', bool $dismissible = false): void
{
$this->icon = match ($type) {
'success' => '✓',
'error' => '✖',
default => 'ℹ',
};
$this->classes = "alert alert-{$type}"
. ($dismissible ? ' alert-dismissible' : '');
}
}
Create the component template
views/components/alert.lex
<div class="{{ $classes }}">
<span>{{ $icon }}</span>
{!! $slot !!}
#if ($dismissible)
<button class="close">×</button>
#endif
</div>
Register the namespace
$lexer->componentClassNamespace('App\\View\\Components');
Lex will now find AlertComponent automatically whenever it encounters <Alert>.Use the component in a template
<Alert type="success" dismissible>
Your profile has been updated.
</Alert>
<Alert type="error">
Failed to save changes.
</Alert>
Without a component class
Component classes are optional. If you don’t need PHP logic, omit the class entirely — the component template receives props directly as variables. See Components for the full props reference.