Содержание
Коротко
Вышел 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 без версии. Значит, можно планировать апгрейд, а не ловить его «случайно».
На практике
- Перед сменой версии прогоните
upgrade-checkпо HTML/шаблонам: найдёт места без:inherited, старые имена событий и удалённые атрибуты. - Ищите родительские
hx-headers,hx-confirm,hx-targetнад элементами сhx-*запросами — почти наверняка нужен:inherited. - Там, где важны фокус и поля ввода, попробуйте
hx-swap="innerMorph"илиouterMorphвместо полной замены узла; стабильныеidпомогают алгоритму. - Для нескольких целей в одном ответе сервера предпочитайте
<hx-partial>с явнымhx-target— проще сопровождать, чем набор скрытых блоков «мимо» основной цели. - Если нужен мягкий переход, смотрите расширение совместимости с 2.x; для продакшена пините версию скрипта, а не «голый» CDN
latest.
Итог
htmx 4.0 укрепляет модель «поведение в разметке»: современные запросы через fetch(), честное наследование атрибутов, слияние узлов из коробки и явные мульти-обновления через <hx-partial>. Имеет смысл мигрировать осознанно — с чекером и тестами шаблонов — а не ждать, пока latest когда‑нибудь переключится сам.

