Attributes
Data attributes have special casing rules, and can be aliased to avoid conflicts with other libraries.
The Datastar VSCode extension and IntelliJ plugin provide autocompletion for all data-*
attributes.
data-attr
#
Sets the value of any HTML attribute to an expression, and keeps it in sync.
1<div data-attr-title="$foo"></div>
The data-attr
attribute can also be used to set the values of multiple attributes on an element using a set of key-value pairs, where the keys represent attribute names and the values represent expressions.
1<div data-attr="{title: $foo, disabled: $bar}"></div>
data-bind
#
Creates a signal (if one doesn’t already exist) and sets up two-way data binding between it and an element’s value. This means that the value of the element is updated when the signal changes, and the signal is updated when the value of the element changes.
The data-bind
attribute be placed on any HTML element on which data can be input or choices selected from (input
, select
,textarea
elements, and web components). Event listeners are added for change
, input
and keydown
events.
1<input data-bind-foo />
The signal name can be specified in the key (as above), or in the value (as below). This can be useful depending on the templating language you are using.
1<input data-bind="foo" />
The initial value of the signal is set to the value of the element, unless a signal has already been defined. So in the example below, $foo
is set to bar
.
1<input data-bind-foo value="bar" />
Whereas in the example below, $foo
inherits the value baz
of the predefined signal.
Multiple input values can be assigned to a single signal by predefining the signal as an array. So in the example below, $foo
is set to ['bar', 'baz']
when both checkboxes are checked.
Modifiers
Modifiers allow you to modify behavior when binding signals.
__case
– Converts the casing of the signal name..camel
– Camel case:mySignal
(default).kebab
– Kebab case:my-signal
.snake
– Snake case:my_signal
.pascal
– Pascal case:MySignal
1<input data-bind-my-signal__case.kebab />
data-class
#
Adds or removes a class to or from an element based on an expression.
1<div data-class-hidden="$foo"></div>
If the expression evaluates to true
, the hidden
class is added to the element; otherwise, it is removed.
The data-class
attribute can also be used to add or remove multiple classes from an element using a set of key-value pairs, where the keys represent class names and the values represent expressions.
1<div data-class="{hidden: $foo, 'font-bold': $bar}"></div>
Modifiers
Modifiers allow you to modify behavior defining a class name.
__case
– Converts the casing of the class..camel
– Camel case:myClass
.kebab
– Kebab case:my-class
(default).snake
– Snake case:my_class
.pascal
– Pascal case:MyClass
1<div data-class-my-class__case.camel="$foo"></div>
data-computed
#
Creates a signal that is computed based on an expression. The computed signal is read-only, and its value is automatically updated when any signals in the expression are updated.
1<div data-computed-foo="$bar + $baz"></div>
Computed signals are useful for memoizing expressions containing other signals. Their values can be used in other expressions.
Computed signals must not be used for performing actions (changing other signals, actions, JavaScript functions, etc.). If you need to perform an action in response to a signal change, use the data-effect
attribute.
Modifiers
Modifiers allow you to modify behavior when defining computed signals.
__case
– Converts the casing of the signal name..camel
– Camel case:mySignal
(default).kebab
– Kebab case:my-signal
.snake
– Snake case:my_signal
.pascal
– Pascal case:MySignal
1<div data-computed-my-signal__case.kebab="$bar + $baz"></div>
data-effect
#
Executes an expression on page load and whenever any signals in the expression change. This is useful for performing side effects, such as updating other signals, making requests to the backend, or manipulating the DOM.
1<div data-effect="$foo = $bar + $baz"></div>
data-ignore
#
Datastar walks the entire DOM and applies plugins to each element it encounters. It’s possible to tell Datastar to ignore an element and its descendants by placing a data-ignore
attribute on it. This can be useful for preventing naming conflicts with third-party libraries, or when you are unable to escape user input.
Modifiers
__self
– Only ignore the element itself, not its descendants.
data-ignore-morph
#
Similar to the data-ignore
attribute, the data-ignore-morph
attribute tells the PatchElements
watcher to skip processing an element and its children when morphing elements.
To remove thedata-ignore-morph
attribute from an element, simply patch the element with thedata-ignore-morph
attribute removed.
data-indicator
#
Creates a signal and sets its value to true
while an SSE request request is in flight, otherwise false
. The signal can be used to show a loading indicator.
This can be useful for show a loading spinner, disabling a button, etc.
The signal name can be specified in the key (as above), or in the value (as below). This can be useful depending on the templating language you are using.
1<button data-indicator="fetching"></button>
Modifiers
Modifiers allow you to modify behavior when defining indicator signals.
__case
– Converts the casing of the signal name..camel
– Camel case:mySignal
(default).kebab
– Kebab case:my-signal
.snake
– Snake case:my_signal
.pascal
– Pascal case:MySignal
data-json-signals
#
Sets the text content of an element to a reactive JSON stringified version of signals. Useful when troubleshooting an issue.
You can optionally provide a filter object to include or exclude specific signals using regular expressions.
1<!-- Only show signals that include "user" in their path -->
2<pre data-json-signals="{include: /user/}"></pre>
3
4<!-- Show all signals except those ending with "temp" -->
5<pre data-json-signals="{exclude: /temp$/}"></pre>
6
7<!-- Combine include and exclude filters -->
8<pre data-json-signals="{include: /^app/, exclude: /password/}"></pre>
Modifiers
Modifiers allow you to modify the output format.
__terse
– Outputs a more compact JSON format without extra whitespace. Useful for displaying filtered data inline.
data-on
#
Attaches an event listener to an element, executing an expression whenever the event is triggered.
1<button data-on-click="$foo = ''">Reset</button>
An evt
variable that represents the event object is available in the expression.
1<div data-on-myevent="$foo = evt.detail"></div>
The data-on
attribute works with events and custom events. The data-on-submit
event listener prevents the default submission behavior of forms.
Events listeners are only triggered when the event is trusted. This behavior can be bypassed using the __trusted
modifier.
Modifiers
Modifiers allow you to modify behavior when events are triggered. Some modifiers have tags to further modify the behavior.
__once
* – Only trigger the event listener once.__passive
* – Do not callpreventDefault
on the event listener.__capture
* – Use a capture event listener.__case
– Converts the casing of the event..camel
– Camel case:myEvent
.kebab
– Kebab case:my-event
(default).snake
– Snake case:my_event
.pascal
– Pascal case:MyEvent
__delay
– Delay the event listener..500ms
– Delay for 500 milliseconds (accepts any integer)..1s
– Delay for 1 second (accepts any integer).
__debounce
– Debounce the event listener..500ms
– Debounce for 500 milliseconds (accepts any integer)..1s
– Debounce for 1 second (accepts any integer)..leading
– Debounce with leading edge..notrail
– Debounce without trailing edge.
__throttle
– Throttle the event listener..500ms
– Throttle for 500 milliseconds (accepts any integer)..1s
– Throttle for 1 second (accepts any integer)..noleading
– Throttle without leading edge..trail
– Throttle with trailing edge.
__viewtransition
– Wraps the expression indocument.startViewTransition()
when the View Transition API is available.__window
– Attaches the event listener to thewindow
element.__outside
– Triggers when the event is outside the element.__prevent
– CallspreventDefault
on the event listener.__stop
– CallsstopPropagation
on the event listener.__trusted
– Runs the expression even if theisTrusted
property on the event isfalse
.
* Only works with built-in events.
data-on-intersect
#
Runs an expression when the element intersects with the viewport.
1<div data-on-intersect="$intersected = true"></div>
Modifiers
Modifiers allow you to modify the element intersection behavior and the timing of the event listener.
__once
– Only triggers the event once.__half
– Triggers when half of the element is visible.__full
– Triggers when the full element is visible.__delay
– Delay the event listener..500ms
– Delay for 500 milliseconds (accepts any integer)..1s
– Delay for 1 second (accepts any integer).
__debounce
– Debounce the event listener..500ms
– Debounce for 500 milliseconds (accepts any integer)..1s
– Debounce for 1 second (accepts any integer)..leading
– Debounce with leading edge..notrail
– Debounce without trailing edge.
__throttle
– Throttle the event listener..500ms
– Throttle for 500 milliseconds (accepts any integer)..1s
– Throttle for 1 second (accepts any integer)..noleading
– Throttle without leading edge..trail
– Throttle with trailing edge.
__viewtransition
– Wraps the expression indocument.startViewTransition()
when the View Transition API is available.
1<div data-on-intersect__once__full="$fullyIntersected = true"></div>
data-on-interval
#
Runs an expression at a regular interval. The interval duration defaults to one second and can be modified using the __duration
modifier.
1<div data-on-interval="$count++"></div>
Modifiers
Modifiers allow you to modify the interval duration.
__duration
– Sets the interval duration..500ms
– Interval duration of 500 milliseconds (accepts any integer)..1s
– Interval duration of 1 second (default)..leading
– Execute the first interval immediately.
__viewtransition
– Wraps the expression indocument.startViewTransition()
when the View Transition API is available.
1<div data-on-interval__duration.500ms="$count++"></div>
data-on-load
#
Runs an expression when the element is loaded into the DOM.
1<div data-on-load="$count = 1"></div>
Modifiers
Modifiers allow you to add a delay to the event listener.
__delay
– Delay the event listener..500ms
– Delay for 500 milliseconds (accepts any integer)..1s
– Delay for 1 second (accepts any integer).
__viewtransition
– Wraps the expression indocument.startViewTransition()
when the View Transition API is available.
1<div data-on-load__delay.500ms="$count = 1"></div>
data-on-signal-patch
#
Runs an expression whenever one or more signals are patched. This is useful for tracking changes, updating computed values, or triggering side effects when data updates.
1<div data-on-signal-patch="console.log('A signal changed!')"></div>
The patch
variable is available in the expression and contains the signal patch details. You can filter which signals to watch using the data-on-signal-patch-filter
attribute.
The data-on-signal-patch-filter
attribute accepts an object with include
and/or exclude
properties that can be regular expressions.
1<!-- Only react to counter signal changes -->
2<div data-on-signal-patch-filter="{include: /^counter$/}"></div>
3
4<!-- React to all changes except those ending with "changes" -->
5<div data-on-signal-patch-filter="{exclude: /changes$/}"></div>
6
7<!-- Combine include and exclude filters -->
8<div data-on-signal-patch-filter="{include: /user/, exclude: /password/}"></div>
Modifiers
Modifiers allow you to modify the timing of the event listener.
__delay
– Delay the event listener..500ms
– Delay for 500 milliseconds (accepts any integer)..1s
– Delay for 1 second (accepts any integer).
__debounce
– Debounce the event listener..500ms
– Debounce for 500 milliseconds (accepts any integer)..1s
– Debounce for 1 second (accepts any integer)..leading
– Debounce with leading edge..notrail
– Debounce without trailing edge.
__throttle
– Throttle the event listener..500ms
– Throttle for 500 milliseconds (accepts any integer)..1s
– Throttle for 1 second (accepts any integer)..noleading
– Throttle without leading edge..trail
– Throttle with trailing edge.
1<div data-on-signal-patch__debounce.500ms="doSomething()"></div>
data-preserve-attr
#
Preserves the value of an attribute when morphing DOM elements.
You can preserve multiple attributes by separating them with a space.
data-ref
#
Creates a new signal that is a reference to the element on which the data attribute is placed.
1<div data-ref-foo></div>
The signal name can be specified in the key (as above), or in the value (as below). This can be useful depending on the templating language you are using.
1<div data-ref="foo"></div>
The signal value can then be used to reference the element.
1$foo is a reference to a <span data-text="$foo.tagName"></span> element
Modifiers
Modifiers allow you to modify behavior when defining references.
__case
– Converts the casing of the key..camel
– Camel case:myKey
.kebab
– Kebab case:my-key
(default).snake
– Snake case:my_key
.pascal
– Pascal case:MyKey
1<div data-ref-my-signal__case.kebab></div>
data-show
#
Shows or hides an element based on whether an expression evaluates to true
or false
. For anything with custom requirements, use data-class
instead.
1<div data-show="$foo"></div>
To prevent flickering of the element before Datastar has processed the DOM, you can add a display: none
style to the element to hide it initially.
1<div data-show="$foo" style="display: none"></div>
data-signals
#
Patches (adds, updates or removes) one or more signals into the existing signals. Values defined later in the DOM tree override those defined earlier.
1<div data-signals-foo="1"></div>
Signals can be nested using dot-notation.
1<div data-signals-foo.bar="1"></div>
The data-signals
attribute can also be used to patch multiple signals using a set of key-value pairs, where the keys represent signal names and the values represent expressions.
1<div data-signals="{foo: {bar: 1, baz: 2}}"></div>
The value above is written in JavaScript object notation, but JSON, which is a subset and which most templating languages have built-in support for, is also allowed.
Setting a signals value to null
will remove the signal.
1<div data-signals="{foo: null}"></div>
Keys used in data-signals-*
are converted to camel case, so the signal name mySignal
must be written as data-signals-my-signal
or data-signals="{mySignal: 1}"
.
Signals beginning with an underscore are not included in requests to the backend by default. You can opt to include them by modifying the value of the filterSignals
option.
Signal names cannot begin with nor contain a double underscore (__
), due to its use as a modifier delimiter.
Modifiers
Modifiers allow you to modify behavior when patching signals.
__case
– Converts the casing of the signal name..camel
– Camel case:mySignal
(default).kebab
– Kebab case:my-signal
.snake
– Snake case:my_signal
.pascal
– Pascal case:MySignal
__ifmissing
Only patches signals if their keys do not already exist. This is useful for setting defaults without overwriting existing values.
data-text
#
Binds the text content of an element to an expression.
1<div data-text="$foo"></div>
Pro Attributes #
The Pro attributes add functionality to the free open source Datastar framework. These attributes are available under a commercial license that helps fund our open source work.
data-animate
#Pro
Allows you to animate element attributes over time. Animated attributes are updated reactively whenever signals used in the expression change.
data-custom-validity
#Pro
Allows you to add custom validity to an element using an expression. The expression must evaluate to a string that will be set as the custom validity message. If the string is empty, the input is considered valid. If the string is non-empty, the input is considered invalid and the string is used as the reported message.
data-on-raf
#Pro
Runs an expression on every requestAnimationFrame
event.
1<div data-on-raf="$count++"></div>
Modifiers
Modifiers allow you to modify the timing of the event listener.
__throttle
– Throttle the event listener..500ms
– Throttle for 500 milliseconds (accepts any integer)..1s
– Throttle for 1 second (accepts any integer)..noleading
– Throttle without leading edge..trail
– Throttle with trailing edge.
1<div data-on-raf__throttle.10ms="$count++"></div>
data-on-resize
#Pro
Runs an expression whenever an element’s dimensions change.
1<div data-on-resize="$count++"></div>
Modifiers
Modifiers allow you to modify the timing of the event listener.
__debounce
– Debounce the event listener..500ms
– Debounce for 500 milliseconds (accepts any integer)..1s
– Debounce for 1 second (accepts any integer)..leading
– Debounce with leading edge..notrail
– Debounce without trailing edge.
__throttle
– Throttle the event listener..500ms
– Throttle for 500 milliseconds (accepts any integer)..1s
– Throttle for 1 second (accepts any integer)..noleading
– Throttle without leading edge..trail
– Throttle with trailing edge.
1<div data-on-resize__debounce.10ms="$count++"></div>
data-persist
#Pro
Persists signals in local storage. This is useful for storing values between page loads.
1<div data-persist></div>
The signals to be persisted can be filtered by providing a value that is an object with include
and/or exclude
properties that can be regular expressions.
1<div data-persist="{include: /foo/, exclude: /bar/}"></div>
Modifiers
Modifiers allow you to modify the storage target.
__session
– Persists signals in session storage.
1<div data-persist__session></div>
data-query-string
#Pro
Syncs query string params to signal values on page load, and syncs signal values to query string params on change.
1<div data-query-string></div>
The signals to be synced can be filtered by providing a value that is an object with include
and/or exclude
properties that can be regular expressions.
1<div data-query-string="{include: /foo/, exclude: /bar/}"></div>
Modifiers
Modifiers allow you to enable history support.
__history
– Enables history support – each time a matching signal changes, a new entry is added to the browser’s history stack. Signal values are restored from the query string params on popstate events.
1<div data-query-string__history></div>
data-replace-url
#Pro
Replaces the URL in the browser without reloading the page. The value can be a relative or absolute URL, and is an evaluated expression.
1<div data-replace-url="`/page${page}`"></div>
data-scroll-into-view
#Pro
Scrolls the element into view. Useful when updating the DOM from the backend, and you want to scroll to the new content.
1<div data-scroll-into-view></div>
Modifiers
Modifiers allow you to modify scrolling behavior.
__smooth
– Scrolling is animate smoothly.__instant
– Scrolling is instant.__auto
– Scrolling is determined by the computedscroll-behavior
CSS property.__hstart
– Scrolls to the left of the element.__hcenter
– Scrolls to the horizontal center of the element.__hend
– Scrolls to the right of the element.__hnearest
– Scrolls to the nearest horizontal edge of the element.__vstart
– Scrolls to the top of the element.__vcenter
– Scrolls to the vertical center of the element.__vend
– Scrolls to the bottom of the element.__vnearest
– Scrolls to the nearest vertical edge of the element.__focus
– Focuses the element after scrolling.
1<div data-scroll-into-view__smooth></div>
data-view-transition
#Pro
Sets the view-transition-name
style attribute explicitly.
1<div data-view-transition="$foo"></div>
Page level transitions are automatically handled by an injected meta tag. Inter-page elements are automatically transitioned if the View Transition API is available in the browser and useViewTransitions
is true
.
Attribute Casing #
According to the HTML specification, all data-*
attributes (not Datastar the framework, but any time a data attribute appears in the DOM) are case in-sensitive, but are converted to camelCase
when accessed from JavaScript by Datastar.
Datastar handles casing of data attributes in two ways:
- The keys used in attributes that define signals (
data-signals-*
,data-computed-*
, etc.), are converted tocamelCase
. For example,data-signals-my-signal
defines a signal namedmySignal
. You would use the signal in a Datastar expression as$mySignal
. - The keys used by all other attributes are, by default, converted to
kebab-case
. For example,data-class-text-blue-700
adds or removes the classtext-blue-700
, anddata-on-rocket-launched
would react to the event namedrocket-launched
.
You can use the __case
modifier to convert between camelCase
, kebab-case
, snake_case
, and PascalCase
, or alternatively use object syntax when available.
For example, if listening for an event called widgetLoaded
, you would use data-on-widget-loaded__case.camel
.
Aliasing Attributes #
It is possible to alias data-*
attributes to a custom alias (data-foo-*
, for example) using the bundler. A custom alias should only be used if you have a conflict with a legacy library and data-ignore
cannot be used.
We maintain a data-star-*
aliased version that can be included as follows.
1<script type="module" src="https://cdn.jsdelivr.net/gh/starfederation/datastar@main/bundles/datastar-aliased.js"></script>
Datastar Expressions #
Datastar expressions used in data-*
attributes can parse signals (prefixed with $
).
A variable el
is available in every Datastar expression, representing the element that the attribute exists on.
1<div id="bar" data-text="$foo + el.id"></div>
Read more about Datastar expressions in the guide.