W↓
All docs
🔑
Sign Up/Sign In
data-star.dev/reference/
Public Link
Apr 12, 2025, 4:55:11 AM - complete - 42.8 kB
Starting URLs:
https://data-star.dev/reference/overview
Crawl Prefixes:
https://data-star.dev/reference/
## Page: https://data-star.dev/reference/overview * Attribute Plugins * Action Plugins * Server-Sent Events * SDKs * Security * Custom Builds ## Attribute Plugins# Attribute plugins are `data-*` attributes that add reactive behavior to HTML elements. ### Core Attributes# | Attribute | Description | | --- | --- | | `data-signals` | Merges one or more signals into the existing signals. | | `data-computed` | Creates a read-only signal computed from an expression. | | `data-star-ignore` | Ignores an element and its descendants when processing. | ### DOM Attributes# | Attribute | Description | | --- | --- | | `data-attr` | Sets any HTML attribute value using expressions. | | `data-bind` | Creates two-way data binding between a signal and an element’s value. | | `data-class` | Adds or removes CSS classes based on expressions. | | `data-on` | Attaches event listeners that execute expressions. | | `data-persist` | Persists signals in Local Storage or Session Storage. | | `data-ref` | Creates a signal reference to the DOM element. | | `data-replace-url` | Replaces the URL in the browser without page reload. | | `data-show` | Shows or hides elements based on expressions. | | `data-text` | Binds text content of an element to an expression. | ### Backend Attributes# | Attribute | Description | | --- | --- | | `data-indicator` | Creates signals that indicate when SSE requests are in flight. | ### Browser Attributes# | Attribute | Description | | --- | --- | | `data-custom-validity` | Adds custom validation to elements. | | `data-on-intersect` | Runs expressions when elements intersect the viewport. | | `data-on-interval` | Runs expressions at regular intervals. | | `data-on-load` | Runs expressions when elements are loaded into the DOM. | | `data-on-raf` | Runs expressions on `requestAnimationFrame` events. | | `data-on-signal-change` | Runs expressions when signals change. | | `data-scroll-into-view` | Scrolls elements into view with various options. | | `data-view-transition` | Sets `view-transition-name` for View Transitions API. | View the attribute plugins reference ## Action Plugins# Action plugins are used in Datastar expressions to perform specific actions. | Action | Description | | --- | --- | | `@get()` | Sends a GET request to the backend and merges the response. | | `@post()` | Sends a POST request to the backend and merges the response. | | `@put()` | Sends a PUT request to the backend and merges the response. | | `@patch()` | Sends a PATCH request to the backend and merges the response. | | `@delete()` | Sends a DELETE request to the backend and merges the response. | ### Browser Actions# | Action | Description | | --- | --- | | `@clipboard()` | Copies the provided evaluated expression to the clipboard. | ### Utility Actions# | Action | Description | | --- | --- | | `@setAll()` | Sets all matching signals to a provided value. | | `@toggleAll()` | Toggles all matching signal values. | | `@fit()` | Makes a value linearly interpolate. | View the action plugins reference ## Server-Sent Events# Datastar uses Server-Sent Events (SSE) to communicate from the server to the client. | Event Type | Description | | --- | --- | | `datastar-merge-fragments` | Merges HTML fragments into the DOM. | | `datastar-merge-signals` | Updates signals with new values. | | `datastar-remove-fragments` | Removes HTML fragments matching selectors. | | `datastar-remove-signals` | Removes signals matching specific paths. | | `datastar-execute-script` | Executes JavaScript in the browser. | View the SSE events reference ## SDKs# Officially supported SDKs for generating Datastar-specific SSE events: * Clojure * C# (.NET) * Go * Haskell * Java * PHP (with Laravel and Craft CMS packages) * Python * Rust * Ruby * TypeScript * Zig View the SDK reference ## Security# Security guidelines for using Datastar expressions safely: | Consideration | Description | | --- | --- | | Escape User Input | Always escape user input to prevent XSS attacks when using Datastar expressions. | | Avoid Sensitive Data | Signal values are visible in source code and can be modified, avoid leaking sensitive data. | | Ignore Unsafe Input | Use `data-star-ignore` to ignore unsafe content that cannot be escaped. | | Content Security Policy | Requires ‘unsafe-eval’ for script sources since Datastar evaluates expressions using IIFE. | View the security reference ## Custom Builds# Datastar is built using a modular architecture that allows you to create custom builds with only the plugins you need, useful for reducing the framework’s footprint. View the custom builds reference --- ## Page: https://data-star.dev/reference/attribute_plugins Datastar provides the following `data-*` attributes. ### Core Attributes# * `data-signals` * `data-computed` * `data-star-ignore` ### DOM Attributes# * `data-attr` * `data-bind` * `data-class` * `data-on` * `data-ref` * `data-show` * `data-text` ### Backend Attributes# * `data-indicator` ### Browser Attributes# * `data-custom-validity` * `data-on-intersect` * `data-on-interval` * `data-on-load` * `data-on-raf` * `data-on-signal-change` * `data-persist` * `data-replace-url` * `data-scroll-into-view` * `data-view-transition` ### Attribute Order# _`data-*` attributes are evaluated in the order they appear in the DOM._ Elements are evaluated by walking the DOM in a depth-first manner, and attributes are processed in the order they appear in the element. This means that if you use a signal in a Datastar expression, it must be defined _before_ it is used. <!-- This works: --> <div data-signals-foo="1" data-text="$foo"></div> <!-- This works: --> <div data-signals-foo="1"></div> <div data-text="$foo"></div> <!-- This works: --> <div data-signals-foo="1"> <div data-text="$foo"></div> </div> <!-- This does NOT work: --> <div data-text="$foo" data-signals-foo="1"></div> <!-- This does NOT work: --> <div data-text="$foo"></div> <div data-signals-foo="1"></div> ### Attribute Casing# _`data-*` attributes have special casing rules._ According to the HTML specification, all `data-*` atttributes (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: 1. **Signal names**: the keys used in attribute plugins that define signals (`data-signals-*`, `data-computed-*`, `data-ref-*`, etc), are, by default, converted to camelCase. For example, `data-signals-my-signal` defines a signal named `mySignal`. You would use the signal in a Datastar expression as `$mySignal`. 2. **All other attribute plugins**: the keys used by all other attribute plugins are, by default, converted to kebab-case. For example, `data-class-text-blue-700` adds or removes the class `text-blue-700`, and `data-on-rocket-launched` would react to the event named `rocket-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 a web component exposes an event `widgetLoaded`, you would use `data-on-widget-loaded__case.camel` to react to it. Whereas, if you wanted to use a signal named `my-signal` then you would use the kebab modfier: `data-signals-my-signal__case.kebab`. ## Core Attributes# The core attribute plugins are included in every bundle, and contain the core functionality in Datastar. ### `data-signals`# Merges one or more signals into the existing signals. Values defined later in the DOM tree override those defined earlier. <div data-signals-foo="1"></div> Signals can be namespaced using dot-notation. <div data-signals-foo.bar="1"></div> Note when working with namespaced signals that only the leaf nodes are actually signals. So in the example above, only `bar` is a signal, meaning that while using `$foo.bar` in an expression is possible, using `$foo` (the namespace) is not. The `data-signals` attribute can also be used to merge multiple signals using a set of key-value pairs, where the keys represent signal names and the values represent expressions. <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. 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 considered _local signals_ and are not included in requests to the backend by default. You can include them by setting the `includeLocal` option to `true`. Signal names cannot begin or contain double underscores (`__`), due to its use as a modifer delimiter. #### Modifiers# Modifiers allow you to modify behavior when merging 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 merges signals if their keys do not already exist. This is useful for setting defaults without overwriting existing values. <div data-signals-my-signal__case.kebab="1" data-signals-foo__ifmissing="1"></div> When supplying signals in bulk with object notation, modifiers can also be used: <!-- Merges the signal `mySignal` --> <div data-signals="{mySignal: 'value'}"></div> <!-- Merges the signal `mySignal` only if it doesn't already exist --> <div data-signals__ifmissing="{mySignal: 'init-value'}"></div> <!-- Defines a kebab cased signal `my-signal` using object notation --> <div data-signals="{'my-signal': 'value'}"></div> <!-- It is possible to set both `data-signals__ifmissing` and `data-signals` on the same element --> <div data-signals="{'my-signal': 'value'}" data-signals__ifmissing="{widgetStatus: 'initial'}"> </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. <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. <div data-computed-foo="$bar + $baz"></div> <div data-text="$foo"></div> `data-computed` is a pure reactive function, this has several implications: 1. If a computed signal is not consumed, then the computation will not execute. 2. Computed signals must not be used for performing actions (changing other signals, actions, JavaScript functions, etc.). <!-- This computation will never execute because $foo is not used anywhere --> <div data-computed-foo="$bar + $baz"></div> <!-- WRONG --> <!-- Computed signals must *not* be used for side effects --> <div data-computed-qux="@post('/qux'); 'quxed'"></div> <!-- WRONG --> <div data-computed-foo="$bar++"></div> <!-- WRONG --> If you find yourself wanting to perform some action in reaction to a signal change, refer to the `data-on-signal-change` 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` <div data-computed-my-signal__case.kebab="$bar + $baz"></div> ### `data-star-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-star-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. <div data-star-ignore data-show-thirdpartylib> <div data-show-thirdpartylib> These element will not be processed by Datastar. </div> </div> #### Modifiers# * `__self` - Only ignore the element itself, not its descendants. ## DOM Attributes# Allow the usage of signals and expressions to affect the DOM. ### `data-attr`# Sets the value of any HTML attribute to an expression, and keeps it in sync. <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. <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. <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. <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`. <input data-bind-foo value="bar" /> Whereas in the example below, `$foo` inherits the value `baz` of the predefined signal. <div data-signals-foo="baz"> <input data-bind-foo value="bar" /> </div> 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. <div data-signals-foo="[]"> <input data-bind-foo type="checkbox" value="bar" /> <input data-bind-foo type="checkbox" value="baz" /> </div> #### 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` <input data-bind-my-signal__case.kebab /> ### `data-class`# Adds or removes a class to or from an element based on an expression. <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. <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` <div data-class-my-class__case.camel="$foo"></div> ### `data-on`# Attaches an event listener to an element, executing an expression whenever the event is triggered. <button data-on-click="$foo = ''">Reset</button> An `evt` variable that represents the event object is available in the expression. <div data-on-myevent="$foo = evt.detail"></div> The `data-on` attribute works with built-in events and custom events. Note that the `data-on-submit` event listener prevents the default submission behavior of forms. #### 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 call `preventDefault` 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` * `__debounce` - Debounce the event listener. * `.500ms` - Debounce for 500 milliseconds. * `.1s` - Debounce for 1 second. * `.leading` - Debounce with leading edge. * `.notrail` - Debounce without trailing edge. * `__throttle` - Throttle the event listener. * `.500ms` - Throttle for 500 milliseconds. * `.1s` - Throttle for 1 second. * `.noleading` - Throttle without leading edge. * `.trail` - Throttle with trailing edge. * `__viewtransition` - Wraps the expression in `document.startViewTransition()` when the View Transition API is available. * `__window` - Attaches the event listener to the `window` element. * `__outside` - Triggers when the event is outside the element. * `__prevent` - Calls `preventDefault` on the event listener. * `__stop` - Calls `stopPropagation` on the event listener. \* Only works on built-in events. <div data-on-click__window__debounce.500ms.leading="$foo = ''" data-on-my-event__case.camel="$foo = ''"></div> ### `data-ref`# Creates a new signal that is a reference to the element on which the data attribute is placed. <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. <div data-ref="foo"></div> The signal value can then be used to reference the element. `$foo` holds a <span data-text="$foo.tagName"></span> element. #### Modifiers# Modifiers allow you to modify behavior when defining references. * `__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` <div data-ref-my-signal__case.kebab></div> ### `data-show`# Show or hides an element based on whether an expression evaluates to `true` or `false`. For anything with custom requirements, use `data-class` instead. <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. <div data-show="$foo" style="display: none"></div> ### `data-text`# Binds the text content of an element to an expression. <div data-text="$foo"></div> ## Backend Attributes# Add integrations with backend plugin actions. ### `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. <button data-on-click="@get('/endpoint')" data-indicator-fetching></button> This can be useful for show a loading spinner, disabling a button, etc. <button data-on-click="@get('/endpoint')" data-indicator-fetching data-attr-disabled="$fetching"></button> <div data-show="$fetching">Loading...</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. <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` ## Browser Attributes# ### `data-custom-validity`# 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. <form> <input data-bind-foo name="foo" /> <input data-bind-bar name="bar" data-custom-validity="$foo === $bar ? '' : 'Field values must be the same.'" /> <button>Submit form</button> </form> ### `data-on-intersect`# Runs an expression when the element intersects with the viewport. <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. * `__debounce` - Debounce the event listener. * `.500ms` - Debounce for 500 milliseconds. * `.1s` - Debounce for 1 second. * `.leading` - Debounce with leading edge. * `.notrail` - Debounce without trailing edge. * `__throttle` - Throttle the event listener. * `.500ms` - Throttle for 500 milliseconds. * `.1s` - Throttle for 1 second. * `.noleading` - Throttle without leading edge. * `.trail` - Throttle with trailing edge. * `__viewtransition` - Wraps the expression in `document.startViewTransition()` when the View Transition API is available. <div data-on-intersect__once__full="$fullyIntersected = true"></div> ### `data-on-interval`# Runs an expression at a regular interval. The interval duration defaults to 1 second and can be modified using the `__duration` modifier. <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. * `.1s` - Interval duration of 1 second (default). * `.leading` - Execute the first interval immediately. * `__viewtransition` - Wraps the expression in `document.startViewTransition()` when the View Transition API is available. <div data-on-interval__duration.500ms="$count++"></div> ### `data-on-load`# Runs an expression when the element is loaded into the DOM. <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. * `.1s` - Delay for 1 second. * `__viewtransition` - Wraps the expression in `document.startViewTransition()` when the View Transition API is available. <div data-on-load__delay.500ms="$count = 1"></div> ### `data-on-raf`# Runs an expression on every `requestAnimationFrame` event. <div data-on-raf="$count++"></div> #### Modifiers# Modifiers allow you to modify the timing of the event listener. * `__debounce` - Debounce the event listener. * `.500ms` - Debounce for 500 milliseconds. * `.1s` - Debounce for 1 second. * `.leading` - Debounce with leading edge. * `.notrail` - Debounce without trailing edge. * `__throttle` - Throttle the event listener. * `.500ms` - Throttle for 500 milliseconds. * `.1s` - Throttle for 1 second. * `.noleading` - Throttle without leading edge. * `.trail` - Throttle with trailing edge. * `__viewtransition` - Wraps the expression in `document.startViewTransition()` when the View Transition API is available. <div data-on-raf__debounce.10ms="$count++"></div> ### `data-on-signal-change`# Runs an expression whenever a signal changes. <div data-on-signal-change="$count++"></div> A key can be provided to only trigger the event when a specific signal changes. <div data-on-signal-change-foo="$fooCount++"></div> You can use `*` to match a single path segment and `**` to match multiple path segments. <!-- Listen for changes to `$foo.bar.baz` --> <div data-signals-foo.bar.baz="1" data-on-signal-change-foo.*.baz="$fooCount++" data-on-signal-change-foo.**="$fooCount++" ></div> #### Modifiers# Modifiers allow you to modify the timing of the event listener. * `__debounce` - Debounce the event listener. * `.500ms` - Debounce for 500 milliseconds. * `.1s` - Debounce for 1 second. * `.leading` - Debounce with leading edge. * `.notrail` - Debounce without trailing edge. * `__throttle` - Throttle the event listener. * `.500ms` - Throttle for 500 milliseconds. * `.1s` - Throttle for 1 second. * `.noleading` - Throttle without leading edge. * `.trail` - Throttle with trailing edge. * `__viewtransition` - Wraps the expression in `document.startViewTransition()` when the View Transition API is available. <div data-on-signal-change__debounce.100ms="$count++"></div> ### `data-persist`# Persists signals in local storage. This is useful for storing values between page loads. <div data-persist></div> If one or more space-separated values are provided as a string, only those signals are persisted. <div data-persist="foo bar"></div> You can use `*` to match a single path segment and `**` to match multiple path segments. <!-- Persists `$foo.bar.baz` --> <div data-signals-foo.bar.baz="1" data-persist="foo.*.baz" ></div> <!-- Persists `$foo.bar.baz` --> <div data-signals-foo.bar.baz="1" data-persist="foo.**" ></div> #### Modifiers# Modifiers allow you to modify the storage target. * `__session` - Persists signals in session storage. <div data-persist__session="foo bar"></div> ### `data-replace-url`# Replaces the URL in the browser without reloading the page. The value can be a relative or absolute URL, and is an evaluated expression. <div data-replace-url="`/page${page}`"></div> ### `data-scroll-into-view`# Scrolls the element into view. Useful when updating the DOM from the backend, and you want to scroll to the new content. <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 computed `scroll-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. <div data-scroll-into-view__smooth></div> ### `data-view-transition`# Sets the `view-transition-name` style attribute explicitly. <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`. ## Aliasing Data 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-star-ignore` cannot be used. We maintain a `data-star-*` aliased version that can be included as follows. <script type="module" src="https://cdn.jsdelivr.net/gh/starfederation/datastar@v1.0.0-beta.11/bundles/datastar-aliased.js"></script> --- ## Page: https://data-star.dev/reference/action_plugins Datastar provides the following actions, that can be used in Datastar expressions. ### Backend Actions# * `@get()` * `@post()` * `@put()` * `@patch()` * `@delete()` ### Browser Actions# * `@clipboard()` ### Utility Actions# * `@setAll()` * `@toggleAll()` * `@fit()` ## Backend Actions# Allow for the integration of any backend service that supports SSE. ### `@get()`# Arguments: `@get(url: string, options={})` Sends a `GET` request to the backend using `fetch`, and merges the response with the current DOM and signals. The URL can be any valid URL and the response must contain zero or more Datastar SSE events. <button data-on-click="@get('/endpoint')"></button> By default, all requests are sent with a `{datastar: *}` object containing the current signals (except for local signals whose keys begin with an underscore). When using a `get` request, the signals are sent as a query parameter, otherwise they are send as a JSON body. It is possible to send form encoded requests by setting the `contentType` option to `form`. This sends GET requests using `application/x-www-form-urlencoded` encoding and non-GET requests using `multipart/form-data` encoding. See the form data example. Note that when a page is hidden (in a background tab, for example), the default behavior is for the SSE connection to be closed, and reopened when the page becomes visible again. To keep the connection open when the page is hidden, set the `openWhenHidden` option to `true`. ### `@post()`# Arguments: `@post(url: string, options={})` Works the same as `@get()` but sends a `POST` request to the backend. <button data-on-click="@post('/endpoint')"></button> ### `@put()`# Arguments: `@put(url: string, options={})` Works the same as `@get()` but sends a `PUT` request to the backend. <button data-on-click="@put('/endpoint')"></button> ### `@patch()`# Arguments: `@patch(url: string, options={})` Works the same as `@get()` but sends a `PATCH` request to the backend. <button data-on-click="@patch('/endpoint')"></button> ### `@delete()`# Arguments: `@delete(url: string, options={})` Works the same as `@get()` but sends a `DELETE` request to the backend. <button data-on-click="@delete('/endpoint')"></button> ### Options# All of the actions above take a second argument of options. * `contentType` - The type of content to send. A value of `json` sends all signals in a JSON request. A value of `form` tells the action to look for the closest form to the element on which it is placed (unless a `selector` option is provided), perform validation on the form elements, and send them to the backend using a form request (no signals are sent). Defaults to `json`. * `includeLocal` - Whether to include local signals (those beggining with an underscore) in the request. Defaults to `false`. * `selector` - Optionally specifies a form to send when the `contentType` option is set to `form`. If the value is `null`, the closest form is used. Defaults to `null`. * `headers` - An object containing headers to send with the request. * `openWhenHidden` - Whether to keep the connection open when the page is hidden. Useful for dashboards but can cause a drain on battery life and other resources when enabled. Defaults to `false`. * `retryInterval` - The retry interval in milliseconds. Defaults to `1000` (1 second). * `retryScaler` - A numeric multiplier applied to scale retry wait times. Defaults to `2`. * `retryMaxWaitMs` - The maximum allowable wait time in milliseconds between retries. Defaults to `30000` (30 seconds). * `retryMaxCount` - The maximum number of retry attempts. Defaults to `10`. * `abort` - An AbortSignal object that can be used to cancel the request. <div data-on-click="@get('/endpoint', { includeLocal: true, headers: { 'X-Csrf-Token': 'JImikTbsoCYQ9oGOcvugov0Awc5LbqFsZW6ObRCxuqFHDdPbuFyc4ksPVVa9+EB4Ag+VU6rpc680edNFswIRwg==', }, openWhenHidden: true, })"></div> ### Events# All of the actions above trigger `datastar-sse` events during the SSE request lifecycle. The event type determines the stage of the request. * `started` - Triggered when the SSE request is started. * `finished` - Triggered when the SSE request is finished. * `error` - Triggered when the SSE request encounters an error. * `retrying` - Triggered when the SSE request is retrying. * `retries-failed` - Triggered when the SSE request fails after retrying. <div data-on-datastar-sse="evt.detail.type == 'error' && console.log('SSE error encountered')"></div> ## Browser Actions# Actions for performing browser operations. ### `@clipboard()`# Arguments: `@clipboard(expression: string)` Copies the provided evaluated expression to the clipboard. <div data-on-click="@clipboard('Hello, world!')"></div> ## Utility Actions# ### `@setAll()`# Arguments: `@setAll(paths: string, value: any)` Sets the value of all matching signals to the expression provided in the second argument. The first argument accepts one or more space-separated signal paths. You can use `*` to match a single path segment and `**` to match multiple path segments. <!-- Sets the value of `$foo` --> <div data-signals-foo="false"> <button data-on-click="@setAll('foo', $bar)"></button> </div> <!-- Sets the value of `$foo.bar.baz` --> <div data-signals-foo.bar.baz="false"> <button data-on-click="@setAll('foo.*.baz', true)"></button> </div> <!-- Sets the value of `$foo.bar.baz` --> <div data-signals-foo.bar.baz="false"> <button data-on-click="@setAll('foo.**', true)"></button> </div> ### `@toggleAll()`# Arguments: `@toggleAll(paths: string)` Toggles the value of all matching signals. The first argument accepts one or more space-separated signal paths. You can use `*` to match a single path segment and `**` to match multiple path segments. <!-- Toggles the value of `$foo` --> <div data-signals-foo="false"> <button data-on-change="@toggleAll('foo')"></button> </div> <!-- Toggles the value of `$foo.bar.baz` --> <div data-signals-foo.bar.baz="false"> <button data-on-click="@toggleAll('foo.*.baz')"></button> </div> <!-- Toggles the value of `$foo.bar.baz` --> <div data-signals-foo.bar.baz="false"> <button data-on-click="@toggleAll('foo.**')"></button> </div> ### `@fit()`# Arguments: `@fit(v: number, oldMin: number, oldMax: number, newMin: number, newMax: number, shouldClamp=false, shouldRound=false)` Make a value linear interpolate from an original range to new one. --- ## Page: https://data-star.dev/reference/sse_events Responses to backend plugin actions must contain zero or more Datastar SSE events. The backend SDKs can handle the formatting of SSE events for you. ## Event Types# ### `datastar-merge-fragments`# Merges one or more fragments into the DOM. By default, Datastar merges fragments using Idiomorph, which matches top level elements based on their ID. event: datastar-merge-fragments data: fragments <div id="foo">Hello, world!</div> Additional `data` lines can be added to the response to override the default behavior. | Key | Description | | --- | --- | | `data: selector #foo` | Selects the target element of the `merge` process using a CSS selector. | | `data: mergeMode morph` | Merges the fragment using Idiomorph. This is the default merge strategy. | | `data: mergeMode inner` | Replaces the target’s innerHTML with the fragment. | | `data: mergeMode outer` | Replaces the target’s outerHTML with the fragment. | | `data: mergeMode prepend` | Prepends the fragment to the target’s children. | | `data: mergeMode append` | Appends the fragment to the target’s children. | | `data: mergeMode before` | Inserts the fragment before the target as a sibling. | | `data: mergeMode after` | Inserts the fragment after the target as a sibling. | | `data: mergeMode upsertAttributes` | Merges attributes from the fragment into the target – useful for updating a signals. | | `data: useViewTransition true` | Whether to use view transitions when merging into the DOM. Defaults to `false`. | | `data: fragments` | The HTML fragments to merge into the DOM. | Sample output showing all options: event: datastar-merge-fragments data: selector #foo data: mergeMode append data: useViewTransition true data: fragments <div> data: fragments Hello, world! data: fragments </div> ### `datastar-merge-signals`# Updates the signals with new values. The `onlyIfMissing` line determines whether to update the signals with new values only if the key does not exist. The `signals` line should be a valid `data-signals` attribute. This will get merged into the signals. Sample output showing all options: event: datastar-merge-signals data: onlyIfMissing false data: signals {foo: 1} ### `datastar-remove-fragments`# Removes one or more HTML fragments that match the provided selector from the DOM. Sample output: event: datastar-remove-fragments data: selector #foo ### `datastar-remove-signals`# Removes signals that match one or more provided paths. Sample output: event: datastar-remove-signals data: paths foo.bar data: paths baz ### `datastar-execute-script`# Executes JavaScript in the browser. The `autoRemove` line determines whether to remove the script after execution. Each `attributes` line adds an attribute (in the format `name value`) to the `script` element. Each `script` line contains JavaScript to be executed by the browser. Sample output showing all options: event: datastar-execute-script data: autoRemove true data: attributes type module data: attributes defer true data: script console.log('Hello, world!') data: script console.log('A second greeting') --- ## Page: https://data-star.dev/reference/sdks Datastar provides backend SDKs that simplify the process of generating SSE events specific to Datastar. Alternatively, use your backend as is to send SSE events. If you’d like to contribute an SDK, please follow the Contribution Guidelines. ## Clojure# Clojure SDK and examples. _Author: Jeremy Schoffen_ ## C# (.NET)# C# (.NET) SDK and examples. _Author: Greg H_ ## Go# Go SDK and examples. _Author: Delaney Gillilan_ Other examples: 1 App 5 Stacks ported to Go+Templ+Datastar ## Haskell# Haskell SDK and examples. _Author: Henry Laxen_ ## Java# Java SDK. _Author: Peter Humulock_ ## PHP# PHP SDK and examples. _Author: Ben Croker (PutYourLightsOn)_ ### Laravel# Laravel package ### Craft CMS# Craft CMS plugin Other examples: Craft Datastar Pokemon demo ## Python# Python SDK, examples, and PyPI package, including support for Sanic, Django, Quart and FastAPI. _Author: Felix Ingram_ ## Rust# Rust SDK and examples. _Author: Johnathan Stevers_ ## Ruby# Ruby SDK and examples. _Author: Ismael Celis_ ## TypeScript# TypeScript SDK and examples, including support for NodeJS and Web standard runtimes (Deno, Bun, etc.). _Author: Patrick Marchand_ ## Zig# Zig SDK and examples. _Author: Johnathan Stevers_ --- ## Page: https://data-star.dev/reference/security Datastar expressions are strings that are evaluated in a sandboxed context, in which `ctx` represents the Datastar context. This means that JavaScript can be used in Datastar expressions. ## Escape User Input# The golden rule of security is to never trust user input. This is especially true when using Datastar expressions, which can execute arbitrary JavaScript. When using Datastar expressions, you should always escape user input. This is to prevent, among other issues, Cross Site Scripting (XSS) attacks. ## Avoid Sensitive Data# Keep in mind that signal values are visible in the source code in plain text, and can be modified by the user before being sent in requests. For that reason, you should avoid leaking sensitive data in signals and always implement backend validation. ## Ignore Unsafe Input# If, for some reason, you cannot escape unsafe user input, you should ignore it using the `data-star-ignore` attribute. This tells Datastar to ignore an element and its descendants when processing DOM nodes. ## Content Security Policy# When using a Content Security Policy (CSP), `unsafe-eval` must be allowed for scripts, since Datastar evaluates expressions using an IIFE (Immediately Invoked Function Expression). <meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-eval';" > --- ## Page: https://data-star.dev/reference/custom_builds Datastar consists of a core library and a set of plugins that provide the functionality that makes up the official framework. These plugins have been carefully curated to provided everything required to build modern web applications, while avoiding unnecessary bloat (don’t expect the kitchen sink!). ## Custom Builds# Datastar is built using a modular architecture that allows you to create custom builds that include only the plugins you need. While this is unnecessary for most applications, it can be useful if you want to intentionally reduce the surface area of what Datastar can do. ### Bundler# The easiest way to create a custom build is to use the bundler, which allows you to include only the plugins you need. The bundler will automatically include the core library and any dependencies required by the plugins you select. 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-star-ignore` cannot be used. We maintain a `data-star-*` aliased version that can be included as follows. <script type="module" src="https://cdn.jsdelivr.net/gh/starfederation/datastar@v1.0.0-beta.11/bundles/datastar-aliased.js"></script> ### NPM# Alternatively, you can use the NPM package `@starfederation/datastar` to create a custom build. The NPM package exports all official plugins and bundles, so you can include only the plugins you need. import { load } from '@starfederation/datastar/bundles/datastar-core' import { Class, Show, Text } from '@starfederation/datastar/plugins' load(Class, Show, Text)