Datastar Attributes
This is the complete API reference for Datastar attributes used in Laravel Hyper. Datastar provides the reactive foundation that Hyper builds upon. All standard Datastar attributes work seamlessly in Hyper applications.
TIP
This reference covers standard Datastar attributes. For Hyper-specific extensions like data-error, data-for, data-if, and data-navigate, see Hyper Attributes.
Data Binding & Display
data-signals (Datastar)
Initializes reactive signals on an element. Signals are reactive variables that automatically update the UI when their values change.
Syntax:
<div data-signals="{key: value, key2: value2}"></div>Example:
<div data-signals="{count: 0, name: 'John', items: [1, 2, 3]}">
<!-- Signals available to all child elements -->
</div>Hyper Enhancement
Hyper provides the @signals Blade directive for better Laravel integration. See Blade Directives.
data-bind (Datastar)
Creates two-way data binding between a form element and a signal. Changes in either direction sync automatically.
Syntax:
<input data-bind="signalName" />Modifiers:
__case.camel- Convert to camelCase__case.kebab- Convert to kebab-case__case.snake- Convert to snake_case__case.pascal- Convert to PascalCase
Examples:
Text Input:
<input type="text" data-bind="email" />With Auto-Creation:
<!-- Creates 'username' signal if it doesn't exist -->
<input data-bind="username" value="John" />With Case Conversion:
<input data-bind__case.snake="firstName" />
<!-- Binds to 'first_name' signal -->Supported Elements:
<input>(text, number, email, password, etc.)<textarea><select>(single and multiple)<input type="checkbox"><input type="radio"><input type="file">(base64 encoded)
data-text (Datastar)
Sets the text content of an element to a reactive expression. Automatically escapes HTML for XSS protection.
Syntax:
<div data-text="expression"></div>Examples:
Display Signal:
<p data-text="$username"></p>With Expression:
<p data-text="'Hello, ' + $name + '!'"></p>
<p data-text="$count * 2"></p>
<p data-text="$price.toFixed(2)"></p>Conditional Display:
<p data-text="$items.length > 0 ? $items.length + ' items' : 'No items'"></p>XSS Protection
data-text sets textContent, not innerHTML. HTML tags are automatically escaped and displayed as text.
data-attr:* (Datastar)
Sets HTML attributes dynamically based on reactive expressions. Replace * with any attribute name.
Syntax:
<element data-attr:attributeName="expression"></element>Examples:
Dynamic Links:
<a data-attr:href="'/users/' + $userId">Profile</a>Conditional Attributes:
<button data-attr:disabled="$isProcessing">Submit</button>
<img data-attr:src="$avatar || '/default.jpg'" />Data Attributes:
<div data-attr:data-id="$todoId" data-attr:data-status="$status"></div>Multiple Attributes:
<input data-attr:placeholder="$placeholder"
data-attr:maxlength="$maxLength"
data-attr:required="$isRequired" />Conditionals
data-show (Datastar)
Conditionally shows or hides an element using CSS display property. The element remains in the DOM.
Syntax:
<div data-show="condition"></div>Examples:
Basic Conditional:
<div data-show="$isVisible">
This content is conditionally visible
</div>With Complex Logic:
<div data-show="$user && $user.role === 'admin'">
Admin-only content
</div>Toggle Pattern:
<div data-signals="{showDetails: false}">
<button data-on:click="$showDetails = !$showDetails">Toggle</button>
<div data-show="$showDetails">Details content...</div>
</div>Performance
data-show keeps elements in the DOM (just hidden). For conditional rendering that removes elements from the DOM, use Hyper's data-if.
Events
data-on:* (Datastar)
Attaches event listeners to elements. Replace * with any valid DOM event name.
Syntax:
<element data-on:eventName="expression"></element>Available Modifiers:
__prevent- CallspreventDefault()on the event__stop- CallsstopPropagation()on the event__once- Listener fires only once__passive- Passive event listener__debounce.{time}ms- Debounce execution (with optional.leadingor.trailing)__throttle.{time}ms- Throttle execution (with optional.leadingor.notrailing)__window- Attach listener to window__outside- Trigger when event is outside element__viewtransition- Wrap in View Transition API
Examples:
Click Events:
<button data-on:click="$count++">Increment</button>
<button data-on:click="$count = 0">Reset</button>With preventDefault:
<form data-on:submit__prevent="@postx('/submit')">
<button type="submit">Submit</button>
</form>Debounced Input:
<input data-bind="search"
data-on:input__debounce.300ms="@get('/search?q=' + $search)" />Throttled Event:
<div data-on:scroll__throttle.100ms="handleScroll()">
Content...
</div>Multiple Modifiers:
<button data-on:click__once__prevent="handleAction()">
One-time action
</button>Window Events:
<div data-on:resize__window__throttle.250ms="$width = window.innerWidth">
Window width: <span data-text="$width"></span>
</div>Outside Clicks:
<div data-on:click__outside="$dropdownOpen = false">
<div data-show="$dropdownOpen">Dropdown content</div>
</div>Common Events:
data-on:click- Click eventsdata-on:input- Input change eventsdata-on:change- Change eventsdata-on:submit- Form submissiondata-on:keydown/data-on:keyup- Keyboard eventsdata-on:focus/data-on:blur- Focus eventsdata-on:mouseenter/data-on:mouseleave- Mouse events
Styling
data-class:* (Datastar)
Conditionally adds or removes CSS classes based on reactive expressions.
Syntax:
<!-- Single class -->
<div data-class:className="condition"></div>
<!-- Multiple classes (object syntax) -->
<div data-class="{className: condition, className2: condition2}"></div>Examples:
Single Class:
<div data-class:active="$isActive">
Content
</div>Multiple Classes:
<div data-class="{
'bg-green-500': $status === 'success',
'bg-red-500': $status === 'error',
'bg-blue-500': $status === 'info'
}">
Status indicator
</div>Toggle Classes:
<button data-on:click="$expanded = !$expanded"
data-class:rotate-180="$expanded">
Expand ▼
</button>Active Navigation:
<a href="/dashboard"
data-class:active="$currentPage === 'dashboard'">
Dashboard
</a>data-style:* (Datastar)
Sets inline CSS styles dynamically based on reactive expressions.
Syntax:
<div data-style:propertyName="value"></div>Examples:
Dynamic Colors:
<div data-style:background-color="$theme === 'dark' ? '#000' : '#fff'">
Content
</div>Dynamic Dimensions:
<div data-style:width="$progress + '%'"
data-style:height="'20px'">
Progress bar
</div>Conditional Opacity:
<div data-style:opacity="$isLoading ? '0.5' : '1'">
Content
</div>Advanced Attributes
data-computed:* (Datastar)
Creates a read-only computed signal that automatically recalculates when dependencies change.
Syntax:
<div data-computed:signalName="expression"></div>Examples:
Shopping Cart Total:
<div data-signals="{items: [{price: 10, qty: 2}, {price: 5, qty: 3}]}"
data-computed:total="$items.reduce((sum, item) => sum + (item.price * item.qty), 0)">
<p data-text="'Total: $' + $total"></p>
</div>Full Name:
<div data-signals="{firstName: 'John', lastName: 'Doe'}"
data-computed:names="$firstName + ' ' + $lastName">
<h1 data-text="$names"></h1>
</div>Filtered List:
<div data-signals="{users: [...], searchTerm: ''}"
data-computed:filteredUsers="$users.filter(u => u.name.includes($searchTerm))">
<p data-text="$filteredUsers.length + ' results'"></p>
</div>TIP
Computed signals are cached and only recalculate when their dependencies change, making them efficient for expensive operations.
data-effect (Datastar)
Executes an expression whenever signals in the expression change. Useful for side effects like logging, analytics, or DOM manipulation.
Syntax:
<div data-effect="expression"></div>Examples:
Console Logging:
<div data-effect="console.log('Count changed:', $count)">
<button data-on:click="$count++">Count: <span data-text="$count"></span></button>
</div>Local Storage Sync:
<div data-effect="localStorage.setItem('theme', $theme)">
<select data-bind="theme">
<option value="light">Light</option>
<option value="dark">Dark</option>
</select>
</div>data-ref (Datastar)
Creates a reference to an element that can be accessed .
Syntax:
<element data-ref="referenceName"></element>Examples:
Focus Management:
<div data-signals="{showModal: false}">
<button data-on:click="$showModal = true; $modalInput.focus()">
Open Modal
</button>
<div data-show="$showModal">
<input data-ref="modalInput" />
</div>
</div>Scroll to Element:
<button data-on:click="$section.scrollIntoView({ behavior: 'smooth' })"
class="p-2 bg-blue-500 text-white rounded">
Scroll to Section
</button>
<div style="height: 1000px;"></div>
<div data-ref="section" class="p-5 bg-gray-200 rounded">
Target section content
</div>Element Measurements:
<div data-ref="box"
data-on:click="$width = $box.offsetWidth">
<p data-text="'Width: ' + $width + 'px'"></p>
</div>data-on-intersect (Datastar)
Triggers an expression when an element enters or exits the viewport using IntersectionObserver.
Syntax:
<element data-on-intersect="expression"></element>Modifiers:
__once- Trigger only once__half- Trigger when 50% visible__full- Trigger when 100% visible__threshold.{0-1}- Custom visibility threshold__rootMargin.{value}- Root margin (e.g.,100px)
Examples:
Lazy Loading:
<img data-attr:src="$loaded ? $imageUrl : '/placeholder.jpg'"
data-on-intersect__once="$loaded = true" />Infinite Scroll:
<div data-on-intersect__once="@get('/load-more?page=' + $page++)">
Loading sentinel
</div>Scroll Animations:
<div data-on-intersect__half="$visible = true"
data-class:fade-in="$visible">
Animated content
</div>View Tracking:
<article data-on-intersect__once__half="gtag('event', 'article_viewed', {id: $articleId})">
Article content
</article>data-on-interval (Datastar)
Executes an expression repeatedly at specified intervals.
Syntax:
<element data-on-interval="expression"></element>Modifiers:
__duration.{time}ms- Set interval duration (default: 1000ms)__leading- Execute immediately, then at intervals
Examples:
Auto-Refresh Dashboard:
<div data-on-interval__duration.5000ms="@get('/dashboard/stats')">
<!-- Stats that refresh every 5 seconds -->
</div>Countdown Timer:
<div data-signals="{timeLeft: 60}"
data-on-interval__duration.1000ms="$timeLeft > 0 && $timeLeft--">
<p data-text="'Time remaining: ' + $timeLeft + 's'"></p>
</div>Clock:
<div data-signals="{currentTime: new Date().toLocaleTimeString()}"
data-on-interval__duration.1000ms="$currentTime = new Date().toLocaleTimeString()">
<p data-text="$currentTime"></p>
</div>HTTP Actions
These actions make HTTP requests to your Laravel backend. They automatically send signals in the request and process SSE responses.
Hyper CSRF Protection
Hyper provides CSRF-protected versions: @postx, @putx, @patchx, @deletex. See Blade Directives.
@get(url, options) (Datastar)
Makes a GET request. Signals are sent as query parameters.
Syntax:
<element data-on:event="@get('/endpoint', {options})"></element>Examples:
Basic GET:
<button data-on:click="@get('/api/data')">Load Data</button>With Signal Parameters:
<button data-on:click="@get('/search?q=' + $searchTerm)">Search</button>With Options:
<button data-on:click="@get('/data', {
headers: {'X-Custom-Header': 'value'},
openWhenHidden: true
})">Load</button>@post(url, options) (Datastar)
Makes a POST request. Signals are sent in the request body as JSON.
Syntax:
<element data-on:event="@post('/endpoint', {options})"></element>Examples:
Basic POST:
<form data-on:submit__prevent="@post('/api/submit')">
<input data-bind="name" />
<button type="submit">Submit</button>
</form>CSRF Protection
Use @postx instead for CSRF-protected POST requests in Laravel:
<button data-on:click="@postx('/create')">Create</button>@put(url, options) (Datastar)
Makes a PUT request. Use @putx for CSRF protection.
Example:
<button data-on:click="@putx('/api/update/' + $id)">Update</button>@patch(url, options) (Datastar)
Makes a PATCH request. Use @patchx for CSRF protection.
Example:
<button data-on:click="@patchx('/api/patch/' + $id)">Patch</button>@delete(url, options) (Datastar)
Makes a DELETE request. Use @deletex for CSRF protection.
Example:
<button data-on:click="@deletex('/api/delete/' + $id)">Delete</button>Request Options
All HTTP actions accept an options object with these properties:
{
// Request configuration
contentType: 'json' | 'form', // Default: 'json'
headers: { [key: string]: string }, // Custom headers
// Signal filtering
filterSignals: {
include: RegExp, // Include only matching signals
exclude: RegExp // Exclude matching signals
},
// Advanced options
selector: string, // Form selector for submission
openWhenHidden: boolean, // Keep connection open in background
requestCancellation: boolean // Cancel concurrent requests (default: true)
}Automatic Cancellation
Fetch requests automatically terminate when their initiating element is removed from the DOM. This prevents memory leaks and unnecessary network activity when components unmount.
Examples:
Filter Signals:
<button data-on:click="@post('/submit', {
filterSignals: {
include: /^form\./,
exclude: /^temp/
}
})">Submit Form Data Only</button>Custom Headers:
<button data-on:click="@get('/api/data', {
headers: {
'X-API-Key': $apiKey,
'X-Client-Version': '1.0'
}
})">Load</button>Form Content Type:
<button data-on:click="@post('/upload', {
contentType: 'form'
})">Upload</button>Expression Context
All Datastar expressions have access to these special variables:
$signalName- Access any signal (prefix with$)$$refs- Object containing alldata-refelements$$signals- Object containing all signals (for debugging)el- Current element (available in event handlers)event- Event object (in event handlers)
Example:
<div data-on:click="console.log('Element:', el, 'Event:', event, 'All signals:', $$signals)">
Debug Click
</div>Learn More
- Hyper Attributes - Hyper-specific extensions
- Blade Directives - Laravel integration helpers
- Signals - Working with reactive signals
- Events - Event handling patterns
- Official Datastar Docs - Complete Datastar reference

