Мой эксперимент с HTMX и Astro

Делюсь первым опытом работы с библиотекой htmx. Я создал простой сайт, состоящий из главной страницы с первоначальным набором карточек квартир и 5 кнопок, которые выводят отфильтрованные по количеству комнат квартиры.

Стек: Astro + HTMX + Tailwind

Реализация очень простая:

// src/pages/index.astro <form id='filter-form' hx-trigger='change' hx-post='/api/cases' hx-target='#serch-results' hx-swap='innerHTML' hx-indicator='#loading' > ... <label> <input type='radio' name='rooms' value='1' class='hidden peer' /> <div class='hover:border-slate-500 peer-checked:opacity-100 peer-checked:shadow-xl peer-checked:border-slate-400'> 1 комната </div> </label> ... </form> <div id='loading'> Загрузка... </div> <div id='serch-results'></div>

Соответственно, при выборе нового варианта фильтра, по адресу `/api/cases` выполняется POST-запрос с данными о выбранном варианте.


Индикатором рабты запроса является `<div id='loading'>`. Результат (готовый HTML) выводится внутри `<div id='serch-results'></div>`.

На стороне `api` код выглядит примерно так:

// src/pages/api/cases.ts export const POST: APIRoute = async ({ request }) => { const formData = await request.formData() const rooms = formData.get('rooms') // Получаем список комнат на основе rooms return new Response( ` <div> ${filteredFlats.map(flat => ` {some flat html here} `)} </div> `, { status: 200, headers: { 'Content-Type': 'text/html+htmx', }, } )

И это все.

Впечатления

Данный подход к созданию веб-приложений скорее не для меня. Реализация через тот же React кажется проще и с большим потенциалом для доработок. Из того, что мне не понравилось:

  • Размытие логики приложения. Backend не просто возвращает данные, но также занимается и решением задач фронтенда;
  • Необходимость согласования верстки на стороне клиента, и на стороне сервера (в нашем случае это отображение карточек по умолчанию и вывод результатов поиска)

Да, здесь я сам немного усложнил себе задачу, не использовав Page Partials, но их применение в рамках того же Astro в связке с HTMX мне показалось черезчур надуманным.

Но, несмотря на сказанное выше, у меня есть ряд задач, где HTMX подходит идеально: у меня есть несколько старых статичных сайтов и сайтов, реализованных на CMS вроде WordPress. Для них возомжность добавить интерактивности (тем более с использованием Page Partials) является отличной перспективой. Для сайтов, написанных на Next или Astro, я пока что не смог увидеть применения.

P.S. Неожиданная проблема

В данном проекте я подключил View Transitions и это, как окалалось, ломает работу библиотеки HTMX. Стоит вам осуществить переход между страницами, как сайт окончательно превращается в статичный. К счастью, я наткнулся на эту статью, где описано решение: необходимо на страницу с кодом HTXM добавить следующий скрипт

// src/pages/index.astro <script> document.addEventListener('astro:page-load', () => { const contentElement = document.getElementById('filter-form') if (contentElement) { htmx.process(document.body) } }) </script>
22
5 комментариев

На мой взгляд ( я правда этого зверя еще не щупал) -эта технология должна хорошо подойти для кейса , когда страница должна быть статична (ввиду тяжести генерации одной части, хотя бы) с одной стороны, а с другой стороны есть вторая динамичная часть -например клиентские комменты. Когда она загружается чисто на клиенте (disqus, cackle etc) - это жуть . Если динамика не сильная можно периодически пререндерить основную часть, а далее добивать клиенским скриптом дополнения - но тоже не айс. А вот это (htmx) -вроде должно хорошо встать тут. Но для меня это пока в теории. PS : Ваш пример скорее для стандартного решения astro+JS island

Да. Для себя я не нашел сценария, когда бы HTMX был бы полезен. Можно было бы делать виджеты для того же WordPress, как вариант.