You need to get out of the mentality that there have be two states.
Ultimately the frontend state cannot exist without the backend, where data is persisted. Most apps don't need the frontend state, all it really gives you is maybe a better UX? But in most cases the tradeoff in complexity isn't worth it.
This isn't about state, is it? In a classic react app, if I need to display the name of a user, then I fetch it (from the server) once, and display it as many times as I need, in as many forms as I need. There's only server state.
I don't see how it's any simpler to shift partial presentation duties to the backend. Consider this example:
https://htmx.org/examples/active-search/
The backend is supposed to respond with the rows to fill a table. You have an extremely tight coupling between the two. Something as simple as changing the order of the columns would require three releases:
- A new version of the backend endpoint - A frontend change to consume the new endpoint - A version to delete the old endpoint
I'm not trying to be obtuse, but I fail to see how this makes any sense.
Consider something as simple as an action updating content in multiple places. It happens all the time: changing your name and also updating the "Hello $name" in the header, cancelling an order that updates the order list but also the order count ...
There's _four_ ways to do it in HTMX. Each "more sophisticated" than the previous one. Which is one really wants, sophistication, isn't it?
https://htmx.org/examples/update-other-content/
I really struggle to decide which example is worse. Not only the backend needs to be aware of the immediate frontend context, it also needs to be aware of the entire markup.
In example two, a seemingly innocuous renaming of the id of the table would break the feature, because the backend uses it (!) to update the view "out of band".
I'm really trying to be charitable here, but I really wonder what niche this is useful for. It doesn't seem good for anything complex, and if you can only use it for simple things, what value does it bring over plain javascript?
> This isn't about state, is it? In a classic react app, if I need to display the name of a user, then I fetch it (from the server) once, and display it as many times as I need, in as many forms as I need. There's only server state.
No, there's two states here: the frontend state, and the backend state.
The name example is trivial, but in real applications, your state is complex and diverges. You need to constantly sync it, constantly validate it, and you need to do that forever. Most of your bugs will be here. The frontend will say the name is name, but actually it's new_name. How do you do fix that? Query the backend every so often? Maybe have the backend send push updates over a websocket? These are hard problems.
Ultimately, there is only one "true" state, the backend state, but this isn't the state your users see. You can see this in every web app today, even multi-billion dollars ones. I put in some search criteria, maybe a check a few boxes. Refresh? All gone. 90% of the time I'm not even on the same page. Push the back button? Your guess is as good as mine where I go. The backend thinks I'm one place, but the frontend clearly disagrees.
SSR was so simple because it FORCES the sync points. It makes them explicit and unavoidable. With a SPA, YOU have to make the sync points. And keep them in sync and perfect forever. Otherwise your app will just be buggy, and they usually are.
> These are hard problems.
I fail to see how HTMX helps. I fail to see how SSR necessarily helps too. You could be serving a page for an order that's been cancelled by the time the user sees it.
> I put in some search criteria, maybe a check a few boxes. Refresh? All gone
You could see that 20 years ago too, unless you manually stored the state of the form somewhere. Again, what does it have to do with HTMX, or Rect, or SSR?
HTMX helps enhance UX by not having to reload/render the entire page. IME it should be used sparingly.
For your name example, you could use hx-swap-oob to update multiple elements. However if you're submitting a form element, I would just re-render the page.
> You could see that 20 years ago too, unless you manually stored the state of the form somewhere
See, that's my point - it's NOT manual, it's explicit. There's a difference. A form submission and page refresh is just that. It's very clear WHEN the sync happens and WHAT we are syncing.
With a SPA, you throw that all away and you have to do it yourself. And it's almost always done poorly and inconsistently.
> Something as simple as changing the order of the columns would require three releases
Just change that example to just return the entire table element on /search. You could even add/remove columns with a single route response change, vs the multiple changes required to sync the front/backend with a JS framework.