How to keep Datastar code DRY

The question of how to keep things DRY (Don’t Repeat Yourself) comes up often when using Datastar. One commonly used example concerns preventing the repetition of a backend action.

1<button data-on:click="@get('/endpoint')">Click me</button>
2<button data-on:click="@get('/endpoint')">No, click me!</button>
3<button data-on:click="@get('/endpoint')">Click us all!</button>

The common misconception is that Datastar should provide shorthand syntax for the repeated @get action. The answer is that this should be solved using your templating language. For example:

1{% set action = "@get('/endpoint')" %}
2<button data-on:click="{{ action }}">Click me</button>
3<button data-on:click="{{ action }}">No, click me!</button>
4<button data-on:click="{{ action }}">Click us all!</button>

Alternatively, using a loop:

1{% set labels = ['Click me', 'No, click me!', 'Click us all!'] %}
2{% for label in labels %}
3    <button data-on:click="@get('/endpoint')">{{ label }}</button>
4{% endfor %}

Thanks to event bubbling, a single event listener can be attached to a parent element instead of each button:

1<div data-on:click="evt.target.tagName == 'BUTTON' 
2    && @get('/endpoint')
3">
4    <button>Click me</button>
5    <button>No, click me!</button>
6    <button>Click us all!</button>
7</div>

This is the pattern that both the Blinksy and Checkboxes demos use to prevent registering multiple event listeners for the same action, while being able to send a corresponding ID for each button clicked.

1<div data-on:click="evt.target.tagName == 'BUTTON' 
2    && ($id = evt.target.dataset.id)
3    && @get('/endpoint')
4">
5    <button data-id="1">Click me</button>
6    <button data-id="2">No, click me!</button>
7    <button data-id="3">Click us all!</button>
8</div>