4,189 karma · joined November 3, 2012
This is super simple to do if you are using a library to generate HTML in your backend programming language.
> Not just that your server template code now has to determine if it is HTMX request and only render OOB fragments if so.
This is literally just a function that checks for a couple of headers, chooses between two rendering options, and adds a `Vary` response header to take care of the caching. Hardly anything complicated.
> htmx can do it but it's going to be very very difficult and brittle.
The problem with this summary is that it misses the point–htmx is not doing backend stuff, your backend app server is. Htmx is just swapping in what the backend sends.
> it is NOT the only tool for all use cases.
The OP said exactly this, the htmx people have always said this, and no one ever claimed otherwise. There are people out there who don't think in absolute all-or-nothing terms.
And this is how your company ultimately loses in the market. For every bloated incumbent you will get a snappy new competitor. Keep saying 'it's not worth it to try new stuff', right until you finally realize you never learned anything new and now your company made you redundant.
document.addEventListener('htmx:configRequest', evt => {
evt.detail.headers['Accept-Version'] = APP_VERSION;
});
And have a middleware that checks for this header. If it finds a version mismatch, have it respond with an HTTP 400 and a message to update the app to get the latest version. This is pretty similar to what many SPAs are already doing nowadays so it shouldn't come as a big surprise.https://www.reddit.com/r/iOSProgramming/comments/1khv43o/com...
'This technique is known as Server Driven UI and it is used by Uber, AirBnb and several other big players. The idea is to change the UI instantly without submitting a new version. Developer can just add a new entry in JSON, which can map to an existing component (already available in the binary) and then that component gets displayed on the screen.'
If you pitch to your business that you can update the app automatically without an app store submission, they will start salivating, if not foaming at the mouth.
<div class=expander>
<button aria-expanded=false>Expand</button>
<!-- Some other stuff here -->
</div>
And you have some JS that handles the expander's behaviour: for (const expander of document.querySelectorAll('.expander')) {
const btn = expander.querySelector('button');
btn.addEventListener('click', () => {
btn.ariaExpanded = 'true';
});
}
This will work fine for `.expander` divs that are already in the page when the event handler is set up. But suppose you dynamically load new expander divs, what then? Your event handler is not going to retroactively set up their click listeners too.Custom elements solve exactly this problem. You can now do:
<expander-elem>
<button aria-expanded=false>Expand</button>
<!-- Some other stuff here -->
</expander-elem>
And then set up the listener: customElements.define('expander-elem', class extends HTMLElement {
connectedCallback() {
const btn = this.querySelector('button');
btn.addEventListener('click', () => {
btn.ariaExpanded = 'true';
});
}
});
And the browser will ensure that it always sets up the listeners for all of the expanders, no matter whether they are loaded on the page initially or dynamically injected later. Without this you would have had to jump through a bunch of hoops to ensure it. This solves the problem elegantly. select 1+1; -- Result: 2
In HTML: not possible.That's the key difference.