Почему этот релиз стоит прочитать #

8 апреля 2026 вышел Hugo v0.160.1 — патч-релиз, который чинит несколько неприятных panic-сценариев из v0.160.0 (вышедшего четырьмя днями раньше). Вместе они формируют один логический шаг для проектов: 0.160.0 даёт две новые возможности, 0.160.1 закрывает баги, всплывшие сразу после релиза.

Если коротко: одну фичу (CSS-переменные в css.Build) ждали давно те, кто строит CSS через Hugo Pipes; остальные изменения — улучшения для авторов render hooks и фиксы редких краевых случаев. Никаких breaking changes, никаких депрекейтов.

Но фиксы в 0.160.1 — это именно тот случай, когда «пропустил минор и поймал panic в проде». Поэтому пробежать стоит.

Главное за один взгляд #

v0.160.0 (4 апреля 2026) — фичевый минор:

  • CSS-переменные можно инжектить в стили при сборке через css.Build (например, прокинуть значения из конфига).
  • Метод .Position теперь доступен на всех render hooks и стал точнее.
  • Несколько прицельных багфиксов (Position, escape ampersand’ов в link URL, stray quotes в partial-декораторе script-контекста).

v0.160.1 (8 апреля 2026) — patch:

  • Fix: panic при passthrough-элементах в заголовках.
  • Fix: panic при редактировании legacy template names, которые одновременно валидные пути в новой схеме.
  • Fix: RenderShortcodes утекал context markers при отступах.
  • Fix: standalone RenderShortcodes теперь снимает nested page context markers.
  • Fix: автосоздание root sections в мультиязычных сайтах.
  • Чистка: cascade._targetcascade.target (в тестах; deprecation осталось в коде).
  • README: чинены ссылки.

Дальше — что это значит на практике.

CSS-переменные в css.Build 🎨 #

Это главная фича релиза. Если вы используете Hugo Pipes для сборки CSS (а не просто статически копируете файлы из static/), теперь можно прокидывать значения из Hugo-контекста прямо в CSS на этапе сборки.

Раньше для подобного приходилось городить пайплайн через переменные окружения, sed-замены или генерировать .css через Hugo template (что ломает синтаксис LSP-плагинов).

Теперь это выглядит ближе к декларативно:

{{ $opts := dict
    "vars" (dict
        "primary"   site.Params.brand.primary
        "max-width" "1200px"
    )
}}
{{ $css := resources.Get "css/main.css" | css.Build $opts }}
<link rel="stylesheet" href="{{ $css.RelPermalink }}">

В CSS можно ссылаться на эти переменные через специальный hook (@import 'hugo:vars' или подобный, точный синтаксис — в документации css.Build).

Когда полезно: сайтам с темой, где accent-цвет задаётся в hugo.toml и должен применяться к компонентам через CSS переменные; сборкам, где max-width или breakpoint-значения управляются из конфига; multi-tenant билдам.

Нашему блогу это не нужно — у нас ровно один theme и палитра жёстко зафиксирована в :root блоке. Но если вы строите тему-конструктор или multi-сайт — стоит изучить.

Точная позиция в render hooks 📍 #

Вторая фича — расширение .Position на все render hooks (image, link, heading, code-block) с одновременным улучшением точности.

.Position возвращает позицию исходного Markdown-токена в файле. Для отладки и понимания «откуда пришла эта ссылка» — критично.

Сценарий использования:

{{/* render-link.html */}}
{{ $url := .Destination | safeURL }}
{{ if not (urls.Parse $url).IsAbs }}
  {{/* Внутренняя ссылка — проверяем что target существует */}}
  {{ if not (.Page.GetPage (string $url)) }}
    {{ warnf "Битая внутренняя ссылка %q в %s" $url .Position }}
  {{ end }}
{{ end }}
<a href="{{ $url }}">{{ .Text | safeHTML }}</a>

В warning’е теперь будет точное файл:строка исходника поста, а не нечто приблизительное. Проще ловить регрессии после рефакторингов контента.

Багфиксы 0.160.1 🔧 #

Пять патчей, каждый закрывает свой панический сценарий или утечку.

Panic при passthrough в заголовках #

Hugo Goldmark поддерживает passthrough — режим, когда определённые символьные блоки (например, LaTeX-формулы $...$) пропускаются как есть и обрабатываются на клиенте через MathJax/KaTeX.

В 0.160.0 если passthrough-элемент попадал прямо внутрь заголовка (например, ## Формула $E=mc^2$), Hugo падал с panic при сборке. 0.160.1 чинит этот случай: теперь рендерится корректный HTML без падения.

Если вы пишете научный/математический контент с inline-формулами в заголовках — обновление обязательно.

Panic на legacy template names #

Если в проекте есть старая схема именования шаблонов (_default/single.html.html и подобные legacy-варианты), которая одновременно является валидным путём в новой схеме именования Hugo, при редактировании файла Hugo мог падать. 0.160.1 разводит эти кейсы.

RenderShortcodes и context markers #

RenderShortcodes — функция для обработки всех шорткодов внутри переданного контента. Она использует внутренние «context markers» для отслеживания вложенности.

В 0.160.0 эти маркеры могли:

  1. Утекать в финальный HTML, если контент с шорткодами был с отступами (например, внутри списка или blockquote).
  2. Не очищаться при standalone-вызове .RenderShortcodes через .Page.Content после nested-рендеринга.

Оба случая дают видимый «мусор» в выводе (артефакты вида __hugo_ctx0__ и подобные). 0.160.1 чистит маркеры в обеих ситуациях.

Если вы используете шорткоды внутри списков или blockquote’ов — обновляйтесь.

Auto-creation root sections в мультиязычных сайтах #

В мультиязычных сайтах Hugo автоматически создаёт «виртуальные» root section страницы для каждого языка. В 0.160.0 эта логика могла давать сбой (root section не создавалась, или создавалась только для default-языка), что ломало навигацию по неосновным языкам.

Если у вас один язык — пункт мимо. Если несколько — обновление лечит.

cascade.target вместо cascade._target #

Мелкий, но симптоматичный пункт: ключ _target в cascade-конфигурации переименован в target (без подчёркивания). Старая форма помечена как deprecated в коде, всё ещё работает.

Если у вас есть cascade-блоки в front matter:

cascade:
  - _target:                 # ← старая форма
      kind: page
    params:
      foo: bar

Замените на:

cascade:
  - target:                  # ← новая форма
      kind: page
    params:
      foo: bar

Точечная правка, занимает минуту. Запас времени до полного удаления старой формы — обычно несколько релизов.

Чек-лист обновления ✅ #

  1. Поднять версию Hugo до 0.160.1 в Dockerfile / CI-образе или локальном binary. Если вы уже на v0.161.0+ — пропускаем, это пройденная развилка.

  2. Если используете passthrough для математики или специальных Markdown-блоков, и они появляются в заголовках — обновление закрывает panic. Без обновления заголовки-формулы могут быть рассадником сюрпризов.

  3. Если используете cascade._target в front matter, переименовать в cascade.target:

    grep -rln '_target:' content/ | xargs sed -i '' 's/_target:/target:/g'
  4. Если строите CSS через Hugo Pipes, посмотреть документацию css.Build с CSS variables — возможно, сможете заменить sed-замены или env-обвязку на встроенный механизм.

  5. Если пишете кастомные render hooks, проверить, можно ли использовать .Position для лучшей диагностики битых ссылок/изображений в постах.

  6. Стандартный прогон:

    hugo --minify --gc

    Сравнить количество warning’ов до и после. Если новых не появилось — мигрировано чисто.

Итог 🧠 #

Hugo 0.160.x — это не громкий feature drop, а методичное улучшение инфраструктуры: новый удобный механизм для CSS-сборки, более точная диагностика в render hooks, набор фиксов под краевые случаи (passthrough в заголовках, RenderShortcodes с отступами, multilingual sections).

Главная причина обновляться — патч 0.160.1 закрывает несколько panic-сценариев. Если вас они никогда не цепляли, повезло; но «не цепляли» — это не «не зацепят». На статичных сайтах panic при сборке проявляется как сломанный CI и красный билд, что рассинхронизирует прод и репозиторий.

Если уже сидите на 0.161.0 (как мой блог сейчас), всё это вы уже получили транзитом. Если на 0.159 или раньше — есть смысл прыгать сразу на самую свежую stable, минуя промежуточные.

Источники #