← Все статьи

htmx 4.0: запросы через fetch и HTML без лишнего JavaScript

Мажор htmx 4.0: fetch вместо XHR, наследование атрибутов только с :inherited, слияние разметки из коробки и <hx-partial> для нескольких целей.

htmx 4.0: запросы через fetch и HTML без лишнего JavaScript
Содержание

Коротко

Вышел htmx 4.0 — крупный шаг для приложений, где интерактивность задаётся разметкой, а не толстым клиентским скриптом. Внутри запросы идут через fetch() вместо XMLHttpRequest; атрибуты больше не «стекают» на потомков сами — нужен суффикс :inherited; встроены замены со слиянием узлов (innerMorph / outerMorph); тег <hx-partial> позволяет одной ответом обновить несколько целей. Для новичков документация по-прежнему открывается рабочим примером на нескольких строках HTML.

Что произошло

С точки зрения привычных hx-get / hx-post и целей замены библиотека почти та же, но три решения меняют апгрейд. Главное — наследование: в 2.x атрибут на родителе часто применялся к детям «как CSS»; в 4.x без :inherited этого нет. Типичный случай — hx-confirm или заголовки защиты от CSRF на обёртке: без явного суффикса кнопка с hx-delete их не увидит. Команда даёт npx [email protected] upgrade-check по шаблонам и расширение совместимости с 2.x для поэтапного перехода.

Внутри переход на fetch() упрощает расширения (потоковая передача, загрузки файлов) и убирает старые события вида htmx:xhr:*. События приведены к схеме htmx:phase:action (например, htmx:before:request). История по умолчанию больше не кладёт снимки DOM в localStorage: «назад» снова запрашивает страницу и подменяет содержимое — меньше сюрпризов от сторонних скриптов.

Новое для разметки: замены со слиянием подмешивают HTML в текущий DOM (фокус, значение полей, состояние видео), а <hx-partial hx-target="…"> явно описывает несколько обновлений в одном ответе — понятнее, чем только замены «мимо» основной цели.

Рядом в том же выпуске дайджеста мельком: Firefox 155 с расширенным CSS (attr() шире, progress(), alpha()) и окончательное удаление расширений на манифесте второй версии из магазина Chrome (в том числе блокировщик uBlock Origin). Это фон недели, не тема релиза htmx.

Почему это важно

htmx обещает интерфейс, которым управляет сервер через HTML. Неявное наследование было мощным и запутанным: правки родителя внезапно меняли поведение глубоких кнопок. Явный :inherited делает шаблоны читаемее ценой миграции. Слияние узлов и <hx-partial> закрывают частые боли «богатых» экранов без отдельного слоя одностраничного приложения: сохранить локальное состояние при обновлении и одним ответом тронуть список и счётчик.

Важно и продуктово: в npm тег latest пока остаётся на 2.x до начала 2027, линия 4 — next, чтобы не сломать CDN без версии. Значит, можно планировать апгрейд, а не ловить его «случайно».

На практике

  1. Перед сменой версии прогоните upgrade-check по HTML/шаблонам: найдёт места без :inherited, старые имена событий и удалённые атрибуты.
  2. Ищите родительские hx-headers, hx-confirm, hx-target над элементами с hx-* запросами — почти наверняка нужен :inherited.
  3. Там, где важны фокус и поля ввода, попробуйте hx-swap="innerMorph" или outerMorph вместо полной замены узла; стабильные id помогают алгоритму.
  4. Для нескольких целей в одном ответе сервера предпочитайте <hx-partial> с явным hx-target — проще сопровождать, чем набор скрытых блоков «мимо» основной цели.
  5. Если нужен мягкий переход, смотрите расширение совместимости с 2.x; для продакшена пините версию скрипта, а не «голый» CDN latest.

Итог

htmx 4.0 укрепляет модель «поведение в разметке»: современные запросы через fetch(), честное наследование атрибутов, слияние узлов из коробки и явные мульти-обновления через <hx-partial>. Имеет смысл мигрировать осознанно — с чекером и тестами шаблонов — а не ждать, пока latest когда‑нибудь переключится сам.