Перейти к содержимому

Hextra

Тема для движка Hugo

Версия0.13.0 (2026-09-29)
Проверено2026-10-17
Готовность для мультиязычного проекта
вики 92 % проверено 19 из 31
сайт 93 % проверено 20 из 34
как считается
Мнение авторавыберу Выбрана для новой вики. Меню языков и hreflang доработаны своими шаблонами, поиск — по названию и началу статьи (режим summary). (2026-10-17)
Ценабесплатно
ЛицензияMIT
Репозиторийhttps://github.com/imfing/hextra
Демоhttps://imfing.github.io/hextra/
CSSTailwind CSS 4.3, уже собранный в теме (assets/css/compiled/main.css); классы с префиксом hx:
Версия Hugo0.146 и новее (проверено на 0.165)
JavaScriptСвой небольшой JavaScript без фреймворков (меню, переключатели, вкладки, копирование кода)
Node.jsНе нужен для сайта; нужен только чтобы пересобрать CSS темы
Переводы интерфейсаИнтерфейс темы переведён на 21 язык, в том числе en, uk, ru. Португальский только европейский — для бразильского нужен свой файл перевода

Поиск включён сразу и ничего настраивать не нужно. Работает в браузере, на FlexSearch.

Где работаетв браузере посетителя (JavaScript)
На чём построенFlexSearch — небольшая библиотека на JavaScript: ищет прямо в браузере посетителя, сервер ей не нужен. При сборке сайта она скачивается из интернета, дальше лежит на вашем сайте.
Откуда берёт текстыHugo собирает тексты статей в один файл на каждый язык. Браузер скачивает этот файл, только когда человек начинает искать (у тестовой вики русский файл — 78 КБ), поэтому сами страницы остаются лёгкими.
ЯзыкиИщет на всех языках сайта и только на языке текущей страницы. Ищет на любом языке, в том числе на украинском, но формы слов не понимает — только начало слова: «мульти» найдёт «мультиязычность», а «языками» не найдёт статью со словом «языков».
РезультатыВыпадающий список: название статьи, путь к ней и найденный раздел. Если в запросе несколько слов, показывает статьи, где есть хотя бы одно из них: «nginx абракадабра» найдёт все статьи про nginx. Статьи со всеми словами обычно выше, но не всегда: в режиме полного текста по запросу «настройка nginx» первой стоит статья без nginx.
Что можно настроить в теме

Что искать — настройка params.search.flexsearch.index:

  • content — весь текст статей (так по умолчанию);
  • summary — название и начало статьи: поле summary, текст до <!--more--> или первые 70 слов (поле description не используется);
  • heading — названия и заголовки разделов;
  • title — только названия.

Рекомендуем summary. Поиск не понимает формы слов, поэтому полнотекстовый режим подмешивает статьи, где нашлось только одно слово запроса: по «настройка nginx» первой выходит статья без nginx. С summary выдача точная, но термины, по которым статью должны находить, нужно писать в первом абзаце или в summary.

[params.search.flexsearch]
  index = "summary"

Поиск можно и выключить. Поставить другой, например Pagefind, настройкой нельзя — только переделав шаблоны темы.

ОграниченияНе ищет по таблицам и блокам, которые дорисовывает сама тема, — только по тексту статей. На очень большой вики файл с текстами станет тяжёлым — тогда тем более лучше режим summary.
Проверено2026-10-17

Плюсы

  • Готовая раскладка документации: боковое меню по разделам, хлебные крошки, оглавление, переход к следующей странице.
  • Не нужен Node.js: тема работает на одном Hugo, CSS уже собран.
  • Поиск по сайту работает сразу: FlexSearch в браузере, без сервера и внешних сервисов (подробнее — в разделе «Поиск по сайту»).
  • Интерфейс уже переведён на все языки проекта: en, uk, ru, pt.
  • Inject Partials — главный плюс для доработок. В теме заранее есть пустые шаблоны-заготовки в местах, куда обычно нужно что-то добавить. Достаточно создать в своём проекте файл с тем же именем в layouts/_partials/custom/, и Hextra вставит его на все страницы. Саму тему трогать не нужно, поэтому её можно обновлять без потери своих правок. Так устроены и другие хорошие темы Hugo: в Hugo Book это inject/*.html, в PaperMod — extend_head.html и extend_footer.html.
  • Точки встраивания в Hextra: head-end.html — в конец <head> (метатеги, hreflang, счётчики); banner.html — баннер над шапкой; navbar-title.html — логотип и название в шапке; page-begin.html и page-end.html — начало и конец страницы; content-begin.html и content-end.html — до и после текста статьи; footer.html — подвал. В этом просмотрщике через них сделаны hreflang и все таблицы базы.
  • Боковое меню управляется со страницы: sidebar.exclude — скрыть статью или рубрику, sidebar.hide — убрать меню на странице, sidebar.open и separator.
  • Пошаговые инструкции: шорткод steps, внутри — обычные заголовки и текст Markdown, удобно для перевода ИИ.
  • Код подсвечивает сам Hugo при сборке (все языки Chroma), есть кнопка «копировать».
  • Поиск грузит индекс отдельным файлом на язык только при первом поиске — страницы остаются лёгкими.
  • Что попадает в индекс поиска, выбирается настройкой params.search.flexsearch.index: весь текст (content), краткое описание (summary), заголовки (heading) или только названия статей (title) — без правки шаблонов.
  • Тёмная тема, карточки, вкладки, врезки, пошаговые блоки, дерево файлов, диаграммы Mermaid и формулы.
  • Умеет отдавать llms.txt и Markdown-версии страниц для ИИ (включается настройкой).

Минусы

  • Переключатель языков показывает все языки сайта, даже если у страницы нет перевода, и ведёт на главную другого языка.
  • Нет hreflang вообще.
  • Колонка текста ограничена 72rem, а справа всегда оставлено место под оглавление, даже если его выключить. Широкие таблицы не помещаются.
  • toc: false прячет оглавление, но место под него справа остаётся пустым.
  • Оглавление видно только на экране шире 1280 пикселей; на узком окне, планшете и телефоне его нет совсем.
  • Португальский интерфейс — европейский, не бразильский; <html lang> берётся из ключа языка (pt), а не из locale (pt-BR).
  • Свои Tailwind-классы в шаблонах не заработают без пересборки CSS темы через Node.js: в собранный CSS попали только классы самой темы. Проще писать обычный CSS.
  • Первая сборка требует интернет: FlexSearch скачивается с CDN.
  • Почти нет микроразметки Schema.org: у хлебных крошек нет BreadcrumbList, у страниц нет Article в JSON-LD — только несколько meta itemprop из встроенного шаблона Hugo. Добавлять придётся своим кодом через head-end.html.
  • Поиск не понимает словоформы и не ищет по таблицам, которые строит шаблон.

Общее впечатление

Hextra — тема для документации и баз знаний в духе Nextra. На ней собран локальный просмотрщик этой базы, поэтому всё ниже проверено на деле, а не по описанию.

Для каталога или справочника тема подходит хорошо: боковое меню, поиск и переводы интерфейса работают из коробки. Для мультиязычного сайта у неё два серьёзных пробела: меню языков и отсутствие hreflang. Оба закрываются своими файлами поверх темы, примерно за полчаса работы. Без этих доработок публиковать мультиязычный сайт на Hextra не стоит.

Мнение автора: рекомендую тестировать — по сравнению с Lotus Docs на тех же данных Hextra явно выигрывает. Меню языков и hreflang всё равно придётся доработать самому.

Дизайн менять неудобно: CSS темы собран заранее, и для своих Tailwind-классов придётся ставить Node.js и пересобирать стили. Если внешний вид нужен свой, проще писать обычный CSS поверх.

Что пришлось доработать

Переключатель языков показывает только существующие переводы

ПроблемаВ меню языков перечислены все языки сайта. Если у страницы нет перевода, ссылка ведёт на главную страницу другого языка.
Что сделаноСкопировал шаблон меню языков темы в свой проект и добавил одно условие: язык показывается, только если у страницы есть перевод на него. Файлы темы не тронуты, Hugo берёт мою копию вместо темной.
Файлыsite/layouts/_partials/language-switch.html
Объём работынебольшой
Требованиеml-switcher-existing
{{- if or (eq $language.Lang $currentLanguageLang) (where $page.AllTranslations "Language.Lang" $language.Lang) -}}
  … пункт меню языка …
{{- end -}}

hreflang только на существующие переводы

ПроблемаТема не выводит теги hreflang, поисковики не узнают о языковых версиях страницы.
Что сделаноВ штатное место темы для своего кода в head добавил вывод hreflang только для существующих переводов страницы и x-default на английскую версию.
Файлыsite/layouts/_partials/custom/head-end.html
Объём работынебольшой
Требованиеml-hreflang-existing
{{- range .AllTranslations }}
<link rel="alternate" hreflang="{{ .Language.Locale }}" href="{{ .Permalink }}">
{{- end }}

Переводы интерфейса для en, uk, ru, pt-BR

ПроблемаПеревод интерфейса на португальский в теме — европейский: «secção», «Saltar para o conteúdo», «Projecto».
Что сделаноСвой файл перевода в проекте с бразильскими строками; Hugo берёт его вместо файла темы.
Файлыi18n/pt.yaml
Объём работынебольшой
Требованиеml-ui-strings

Атрибут lang в нужном формате

Проблема<html lang> берётся из ключа языка: у бразильского португальского получается pt, а не pt-BR.
Что сделаноКопии шаблонов темы baseof.html и 404.html, в каждой изменена одна строка: lang из locale.
Файлыlayouts/baseof.html layouts/404.html
Объём работынебольшой
Требованиеml-html-lang
<html lang="{{ partial "utils/hugo-compat/language-locale.html" .Site.Language | default .Site.Language.Lang }}" …>

Ширина страницы под широкие таблицы

ПроблемаТаблицы базы не помещаются: текст ограничен 72rem, справа пустая колонка под оглавление, а toc: false её не убирает.
Что сделаноВ своём CSS расширил колонку текста до 100% ширины, а на главной скрыл колонку оглавления.
Файлыsite/assets/css/custom.css
Объём работынебольшой
:root { --hextra-max-content-width: 100%; }
.hextra-max-page-width:has(#stacks) > .hextra-toc { display: none !important; }

Результаты по требованиям с этой темой

Многие результаты задаёт сам Hugo, и они одинаковы для всех тем: языковые адреса, работа без базы данных, генерация страниц из данных. От темы зависят меню языков, hreflang, поиск и места для своего кода — их нужно проверять у каждой темы отдельно. Значок в пунктирной рамке — результат перенесён из проверки с другой темой этого движка. Наведите на значок, чтобы увидеть подробности.

ТребованиеРезультатОт чего зависитПримечание
Мультиязычность
Материал можно начать на неосновном языке ml-author-any-langдадвижокстраница только на ru (/ru/o-proekte/) собирается без заглушки en
Переключатель языков показывает только существующие переводы ml-switcher-existingдоработкатемаHextra 0.13.0 перечисляет все языки, без перевода ведёт на главную языка; исправлено переопределением partial language-switch.html
hreflang только на существующие переводы ml-hreflang-existing проверить ↗доработкатемаHextra 0.13.0 не выводит hreflang вообще; добавлено в custom/head-end.html по .AllTranslations + x-default
Нет автостраниц с контентом основного языка ml-no-fallback-pages проверить ↗датемастатья только на ru существует только на ru; пустых страниц на других языках нет
Основной язык в корне, остальные с префиксом ml-default-rootдадвижокdefaultContentLanguageInSubdir = false: en в корне, ru на /ru/
Атрибут lang в нужном формате ml-html-langдоработкатемаhtml lang берётся из ключа языка (pt), а не из locale; исправлено копиями baseof.html (17 строк) и 404.html — одна строка, lang из locale: pt-BR
Переводы интерфейса для en, uk, ru, pt-BR ml-ui-stringsдоработкатемаинтерфейс переведён на en, uk, ru, но португальский в теме только европейский (i18n/pt.yaml: «secção», «Saltar para o conteúdo», «Projecto»); для pt-BR — свой i18n/pt.yaml в проекте, все 46 строк
Контент доступен для автоматического перевода ИИ ml-ai-translatableдадвижокстатьи — обычные Markdown-файлы; в рабочем проекте их переводит скрипт через Gemini
Статьи, навигация и поиск
Управление боковым меню sidebar-controlдатемадерево всего сайта; на странице sidebar.exclude — скрыть из меню, sidebar.hide — убрать меню, sidebar.open и separator
Оглавление статьи toc-controlдатемасправа от статьи, подсветка текущего раздела, подпись переведена; toc: false прячет оглавление, но пустая колонка справа остаётся. Видно только на экране шире 1280 пикселей: на ноутбуке с узким окном, планшете и телефоне оглавления нет совсем, кнопки вместо него тоже нет — проверено
Таксономии (теги, рубрики, свои классификаторы) taxonomiesдатемаесть шаблоны страниц тегов и терминов, теги выводятся под оглавлением (params.toc.displayTags); по коду темы — в тестовом наборе тегов нет
Поиск по сайту site-searchдатемаиндекс — отдельный JSON на язык (ru — 78 КБ на 17 статей), грузится при первом поиске; страница статьи 87 КБ
Гибкость поиска search-replaceableдоработкатемазамена: только своими копиями шаблонов; языки: любые, формы слов не понимает; где искать: настройкой params.search.flexsearch.index — весь текст, начало статьи (summary Hugo, а не description), заголовки или только названия — все четыре режима проверены
Подсветка кода code-highlightдатемаподсвечивает сам Hugo при сборке (Chroma, все его языки), кнопка «копировать»; чтобы взять цвета темы, в конфиге нужен markup.highlight.noClasses = false
Пошаговые инструкции content-stepsдатемашорткод steps: шаги — это обычные заголовки ### внутри, текст остаётся Markdown
Свой код в шаблоны без правки темы (Inject Partials) theme-inject-partialsдатема8 заготовок в layouts/_partials/custom/: head-end, banner, navbar-title, page-begin, page-end, content-begin, content-end, footer
Генерация страниц из данных (pSEO) data-pagesдадвижокmodule.mounts: data/products → content/cms, data/*.yaml → hugo.Data, без копирования
SEO
Микроразметка schema.org seo-schemaдоработкатематолько базовые meta itemprop из встроенного шаблона Hugo (name, description, wordCount); BreadcrumbList и Article в JSON-LD нет — добавлять своим кодом через head-end.html
Хранение и окружение
Работает без сервера БД no-dbдадвижокSSG, контент в Markdown и YAML
Работает в окружении Nginx + PHP-FPM 8.5 runtime-phpдадвижокPHP не нужен: Nginx отдаёт статику