Writing alpine.js syntax that validates
Apline.js is a fantastic javascript framework for performing simple tasks, like toggeling a element. But by default, it is not valid html.
In this post we take a look on how to use alpine.js with valid html syntax.
Here are the example component we will be working on. It is a simple div that we can show and hide with the click of a button.
<div x-data="{open: false}">
<div x-show="open">It is open</div>
<button x-on:click.prevent="open = ! open">
Toggle me
</button>
</div>
The x-properties are not valid html-syntax, so we have to tell apline to use someting else. In our app.js-file we can define this by calling aplines prefix-method.
import Alpine from 'alpinejs';
window.Alpine = Alpine;
Alpine.prefix("data-x-");
Alpine.start();
That change will make it possible to replace the x-attributes with data-x-attributes, which is valid html syntax.
<div x-data="{open: false}">
<div data-x-data="{open: false}">
<div x-show="open">It is open</div>
<div data-x-show="open">It is open</div>
<button x-on:click.prevent="open = ! open">
<button data-x-on:click.prevent="open = ! open">
Toggle me
</button>
</div>
However, there are still a problem left to solve, the apline modifiers (: and .) are not valid syntax. So we will have to extract these to the javascript end of the code.
<div data-x-data="{open: false}">
<div data-x-data="{
open: false,
buttonBinding: {
['data-x-on:click']() {
this.open = ! open;
}
}}">
<div data-x-data="{open: false}">
<div data-x-show="open">It is open</div>
<button data-x-bind="buttonBinding">
<button data-x-on:click.prevent="open = ! open">
Toggle me
</button>
</div>
This approach can make it working with apline directly in the html end a bit messy if there are a few methods. So as a final refactor, if it grows I would extract it to a apline component.
import Alpine from 'alpinejs';
window.Alpine = Alpine;
Alpine.prefix("data-x-");
Apline.component('example', () => ({
open: false,
buttonBinding: {
['data-x-on:click']() {
this.open = ! open;
}
}
}));
Alpine.start();
<div data-x-data="example">
<div data-x-show="open">It is open</div>
<button data-x-bind="buttonBinding">
Toggle me
</button>
</div>