Writing Plugins
The package’s engine export re-exposes the vendored Datastar plugin API —
attribute(), action(), effect(), signal() and friends. A custom
attribute plugin looks like this:
import { attribute, effect } from '@wrux/astro-datastar/engine';
attribute({
name: 'my-plugin', // matched as data-my-plugin
returnsValue: true, // the attribute value is an expression
apply({ el, rx }) {
// rx() evaluates the attribute expression; effect() re-runs when
// signals the expression reads change.
return effect(() => {
const value = rx();
// …update el…
});
},
});
Register plugins by importing their modules from your app-local entrypoint (see Integration Options). This site’s own plugins are working references:
- collapse — an
effect()-driven animation. - cloak — a boot-time attribute.
- combobox — a larger behavioural plugin with keyboard navigation and live DOM lookups.
The package’s own replace-url plugin is the smallest full example:
import { attribute, effect } from '../engine';
/**
* `data-replace-url="<expression>"` keeps the address bar in sync with
* signal state: whenever signals the expression reads change, the current
* history entry is replaced with the evaluated URL (relative or absolute,
* same-origin only).
*
* ```html
* <div data-replace-url="'/businesses' + ($q ? '?q=' + $q : '')"></div>
* ```
*
* Upstream Datastar 1.0 moved its ReplaceUrl plugin to the paid Pro
* bundle; this is our own minimal equivalent with the same attribute name.
*/
attribute({
name: 'replace-url',
requirement: { key: 'denied', value: 'must' },
returnsValue: true,
apply({ rx }) {
return effect(() => {
const url = rx();
if (typeof url !== 'string' || url === '') return;
const resolved = new URL(url, window.location.origin);
if (resolved.origin !== window.location.origin) return;
history.replaceState(
history.state,
'',
resolved.pathname + resolved.search + resolved.hash,
);
});
},
});