I am a backend/ML engineer and tried using HTMX to create a website with:
* Search box
* Typeahead
* Instantly updating search results
It was super instructive. In the end, I realized HTMX was probably not the best tool for that job, but it really helped me bridge the gap between "I get in theory why we use JS on the FE" and "Ah, I can see why client side JS is the obvious choice for this".
Doesn't a searchbox with typeahead and instantly updating results still require a backend? Isn't that backend not the most important ingredient of this use-case?
Or did you send a large payload of objects to the frontend and have it indexed clientside with e.g. lunr.js?
I've used fuse.js for this, but for a use-case where we knew we had less than a hundred documents to index and where the access control was simple and the content reasonably stable. I'd never use this for a search feature in e.g. an admin backend or a large, content-rich webapp.
Yeah the "pure" backend side (DB/queries to it) was not a problem and something I was already comfortable with. I did not use a client JS library for filtering, I was trying to stick to pure HTML response routes as much as possible. In addition to the typeahead search I had some dropdown and radio toggle filters. I wanted these to all be reactive to each other, eg, you shouldn't be able to select the region "North America" if none of the current typeahead results have that as a region. I found this confusing to implement within the HTMX paradigm. I had a lot of HTML partial templates and had trouble mentally modeling how it was all fitting together.
TBF, probably partially a skill issue. But I know that just going back to a "normal" approach where my backend returned a huge payload and then I wrote the filtering/rendering in JS, was sooo much simpler to think about, even if it resulted in more total code.
I'm working on my first project with htmx and had a similar dilemma. The core issue is that the input form itself has some state, in terms of which options are selected or which options are available. Even in the case of a simple drop down, the user's selection can get cleared if they drill into a result and then hit the browser back button.
At first I was reaching for JS and this feels good—total control! But I wanted to challenge myself to use a hypermedia based approach, and in the end the outcome felt better.
One key insight was that I needed to rerender the form too when I returned the results. At first I only inserted the results into the page and left the form untouched. Later I also realized that if you want to encode the entire search in the url as parameters, then you need a way to render that combo of results and form state on page load anyway.
I guess where it can get tricky is with the templating system. I used FastHTML and wrote all my HTML as Python code. This gives the full expressiveness of the programming language, which is nice, but it seems that templating systems typically provide plenty of logic and control flow. A single template can do a lot. For your example of making only certain regions selectable depending on search results, you could pass the list of regions into the template engine and use a for loop capability in the template.
But hey, you found a way that works and that's great. Just wanted to share that I found with a bit of paradigm shift I found the hypermedia approach really straightforward and clean.
> At first I was reaching for JS and this feels good—total control! But I wanted to challenge myself to use a hypermedia based approach, and in the end the outcome felt better.
I've built a search page that used meilisearch as backend and a simple "SPA" in vanilla JS once.
It was completely "Hypermedia based" because I stored all the state of search/facets/pagination for the SPA in the URL(query args). A URL is limited in what it can store, but its a neat storage for state, especially because it's limited :)
Then if you landed on a page with certain query args, the state would be rebuilt from that, and the request to meilisearch would be constructed from this "state", sent there, and the objects in the response would be the state for the results.
What issues did you run into with this? I do exactly this in a couple of apps. You can use a `keyup changed delay:${delayMs}ms` event, and you target the area on your page where you want search results.
I also took that approach. The problem wasn't the keyup trigger, moreso trying to make the typeahead suggestions play nicely with radio/toggle filters, plus the results, made things really confusing for me personally. I was taking the approach of ONLY returning HTML from my endpoints and found it hard to mentally model how all the templates were fitting together (probably a skill issue, I am very new to webdev).
Once I abandoned the pure HTML/HTMX approach and just focused on returning a big payload with the search results in JSON and rendering it with vanilla JS, the whole thing became a lot easier.
* Search box
* Typeahead
* Instantly updating search results
It was super instructive. In the end, I realized HTMX was probably not the best tool for that job, but it really helped me bridge the gap between "I get in theory why we use JS on the FE" and "Ah, I can see why client side JS is the obvious choice for this".