Directives ​
STX directives are special template attributes that provide powerful functionality for your templates. This guide covers all available directives and their usage.
Core Directives ​
Conditional Rendering ​
@if / @else / @elseif ​
html
@if(user.isAdmin)
<admin-panel />
@elseif(user.isModerator)
<moderator-panel />
@else
<user-panel />
@endif
@unless ​
The opposite of @if
:
html
@unless(user.isVerified)
<verify-email-banner />
@endunless
@show / @hide ​
Shorthand for visibility control:
html
<div @show="isVisible">Visible content</div>
<div @hide="isHidden">Hidden when true</div>
Loops and Iteration ​
@foreach ​
Iterate over arrays and objects:
html
<ul>
@foreach(users as user)
<li>{{ user.name }}</li>
@endforeach
</ul>
<!-- With index -->
<ul>
@foreach(users as user, index)
<li>{{ index + 1 }}. {{ user.name }}</li>
@endforeach
</ul>
<!-- With empty state -->
@foreach(items as item)
<item-card :data="item" />
@empty
<p>No items found</p>
@endforeach
@for ​
Traditional for loop:
html
@for(let i = 0; i < 5; i++)
<span>Item {{ i + 1 }}</span>
@endfor
@while ​
While loop:
html
@while(condition)
<keep-trying />
@endwhile
Layout Control ​
@extends ​
Inherit from a layout:
html
@extends('layouts/main')
@section / @yield ​
Define and render content sections:
html
<!-- Layout -->
<title>@yield('title')</title>
<main>@yield('content')</main>
<!-- Page -->
@section('title', 'My Page')
@section('content')
<h1>Welcome</h1>
@endsection
@include ​
Include other templates:
html
@include('partials/header')
@include('components/card', { title: 'My Card' })
@includeIf('optional/feature')
@includeWhen(user.isAdmin, 'admin/tools')
Component Directives ​
@component ​
Define a component:
html
@ts
interface ButtonProps {
type: 'primary' | 'secondary'
size?: 'sm' | 'md' | 'lg'
}
@endts
@component('Button', {
props: {
type: 'primary',
size: 'md'
}
})
<button class="btn btn-{{ type }} btn-{{ size }}">
<slot></slot>
</button>
@endcomponent
@slot ​
Define named slots:
html
@component('Card')
<slot name="header"></slot>
<slot></slot>
<slot name="footer"></slot>
@endcomponent
<!-- Usage -->
<Card>
@slot('header')
<h2>Card Title</h2>
@endslot
<p>Card content</p>
@slot('footer')
<button>Action</button>
@endslot
</Card>
Event Handling ​
@click ​
Handle click events:
html
<button @click="handleClick">Click Me</button>
<button @click="count++">Increment</button>
@submit ​
Handle form submissions:
html
<form @submit.prevent="handleSubmit">
<!-- form fields -->
</form>
Event Modifiers ​
Add event modifiers with dots:
html
<button @click.stop="handleClick">Stop Propagation</button>
<button @click.prevent="handleClick">Prevent Default</button>
<form @submit.prevent="handleSubmit">Submit</form>
<div @click.once="handleClick">Click Once Only</div>
<button @click.self="handleClick">Self Only</button>
Data Binding ​
@bind ​
Two-way data binding:
html
<input @bind="username" />
<select @bind="selectedOption">
<option value="1">One</option>
<option value="2">Two</option>
</select>
@model ​
Form input binding:
html
<input type="text" @model="user.name" />
<input type="checkbox" @model="isChecked" />
<select @model="selected">
<!-- options -->
</select>
Advanced Directives ​
@memo ​
Memoize expensive computations:
html
@memo(expensiveValue)
<heavy-component :value="expensiveValue" />
@endmemo
@watch ​
Watch for changes:
html
@watch(user.status)
<status-indicator :status="user.status" />
@endwatch
@error ​
Error handling:
html
@error
<div class="error-message">
{{ error.message }}
</div>
@enderror
Custom Directives ​
Create your own directives:
ts
// directives/tooltip.ts
import { defineDirective } from '@stacksjs/stx'
export const tooltip = defineDirective({
mounted(el, { value }) {
el.setAttribute('title', value)
},
updated(el, { value }) {
el.setAttribute('title', value)
}
})
// Usage in template
<button @tooltip="Help text">Hover me</button>
Best Practices ​
Conditional Rendering
- Use
@if
for simple conditions - Use
@switch
for multiple conditions - Consider extracting complex logic to computed properties
- Use
Loops
- Always provide a key for list items
- Use
@empty
for empty states - Consider pagination for large lists
Event Handling
- Use appropriate event modifiers
- Keep event handlers simple
- Consider debouncing/throttling when needed
Component Organization
- Keep directives focused and reusable
- Document custom directives
- Test directive behavior
Next Steps ​
- Learn about Components
- Explore Template Syntax
- Understand TypeScript Integration
- Check out Custom Directives