Hugo: создание и настройка статического сайта шаг за шагом
Hugo — это быстрый генератор статических сайтов (Static Site Generator), написанный на Go. Он превращает контент (Markdown) и шаблоны в готовые HTML-страницы без использования базы данных и серверной логики, что делает сайты очень быстрыми, безопасными и удобными для хостинга.
Практическая рекомендация, что выбрать YAML vs JSON
Hugo читает data‑файлы из каталога data/ в форматах YAML, JSON и TOML, после чего они доступны в шаблонах. Формат данных никак не влияет на конечный HTML: это просто разные способы сериализации ключ‑значение и массивов.
- Если планируешь в основном редактировать данные руками (каталоги тарифов, списки провайдеров, таблицы), бери YAML в data/ и YAML‑front matter в контенте (метаданные страницы).
- Если данные будут почти всегда генерироваться внешними скриптами или подтягиваться из API, можно хранить их как JSON, чтобы не добавлять лишний шаг конвертации.
Технически можно без проблем комбинировать: глобальные справочники в YAML, «сырые» выгрузки из API в JSON — Hugo спокойно обработает оба варианта.
Установка Hugo в Linux
У меня сейчас под рукой Ubuntu 24.04.3 LTS, поэтому протестирую инструкцию на этой ОС. Проще установить Hugo версии из репозитория Ubuntu.
sudo apt update sudo apt install hugo $ hugo version hugo v0.123.7+extended linux/amd64 BuildDate=2025-07-18T03:41:49Z VendorInfo=ubuntu:0.123.7-1ubuntu0.3
Если нужна самая свежая версия, можно скачать .deb с GitHub и поставить через dpkg, но для старта достаточно пакета из дистрибутива.
Не заработала тема с это версией hugo - обновляем системную версию
Скачиваем .deb Hugo Extended нужной версии и устанавливаем через dpkg. Версии hugo смотрим здесь https://github.com/gohugoio/hugo/releases В консоли Linux вводим команды, в переменной HUGO_VER задаем нужную версию hugo.
cd /tmp HUGO_VER=v0.165.0 # или другая актуальная wget https://github.com/gohugoio/hugo/releases/download/v${HUGO_VER}/hugo_extended_${HUGO_VER}_Linux-amd64.tar.gz tar -xzf hugo_extended_${HUGO_VER}_Linux-amd64.tar.gz # В архиве один бинарник hugo sudo mv hugo /usr/local/bin/hugo
Установленный бинарник окажется в /usr/local/bin/hugo, я для простоты использования затер системный бинарник установленный из репозитория. Флаг –force нужен, чтобы Hugo не ругался на то, что в папке уже лежит созданная нами директория bin/.
cp /usr/local/bin/hugo /usr/bin/hugo
Как создать чистый проект с конкретной версией Hugo
Нам нужно проигнорировать версию Hugo установленную в систему и поставить более новую версию, для конкретного проекта. То есть в каждом проекте может использоваться своя версия Hugo.
- hugo_local_install.sh
#!/bin/bash set -euo pipefail # --- Настройки --- HUGO_VER="0.165.0" BIN_DIR="$HOME/bin" # ----------------- case "$(uname -m)" in x86_64) ARCH="amd64" ;; aarch64) ARCH="arm64" ;; *) echo "Неизвестная архитектура: $(uname -m)"; exit 1 ;; esac ASSET="hugo_extended_${HUGO_VER}_linux-${ARCH}.tar.gz" URL="https://github.com/gohugoio/hugo/releases/download/v${HUGO_VER}/${ASSET}" mkdir -p "$BIN_DIR" TMP_DIR=$(mktemp -d) trap 'rm -rf "$TMP_DIR"' EXIT echo "1. Скачиваем Hugo v${HUGO_VER} (${ARCH})..." wget -q "$URL" -O "$TMP_DIR/$ASSET" echo "2. Проверяем checksum..." wget -q "https://github.com/gohugoio/hugo/releases/download/v${HUGO_VER}/hugo_${HUGO_VER}_checksums.txt" -O "$TMP_DIR/checksums.txt" ( cd "$TMP_DIR" && grep " ${ASSET}\$" checksums.txt | sha256sum -c - ) echo "3. Распаковываем в $BIN_DIR..." tar -xzf "$TMP_DIR/$ASSET" -C "$TMP_DIR" hugo mv -f "$TMP_DIR/hugo" "$BIN_DIR/hugo" chmod +x "$BIN_DIR/hugo" echo "4. Прописываем PATH (если ещё не прописан)..." if ! grep -q '# hugo-local-path' "$HOME/.bashrc" 2>/dev/null; then echo -e "\n# hugo-local-path\nexport PATH=\"\$HOME/bin:\$PATH\"" >> "$HOME/.bashrc" fi echo "Готово. Версия:" "$BIN_DIR/hugo" version echo "Перелогиньтесь или выполните: source ~/.bashrc"
В итоге получаем абсолютно чистый стандартный проект, созданный конкретной версией Hugo, без каких-либо внешних тем. Генерируем чистую структуру Hugo:
#!/bin/bash set -e # --- Настройки --- PROJECT_NAME="new_project_latest_hugo" HUGO_VER="0.165.0" # ----------------- PROJECT_DIR="$HOME/$PROJECT_NAME" echo "2. Генерируем чистую структуру Hugo..." cd "$PROJECT_DIR" ./bin/hugo new site . --force echo "3. Инициализируем Git..." git init echo "Готово! Чистый проект создан:" echo "cd $PROJECT_DIR && ./bin/hugo server -D"
Установка Hugo и Hextra в Windows 11
Откройте PowerShell от имени администратора и установите Hugo (обязательно версию extended, так как Hextra использует обработку CSS/SASS):
winget install Hugo.Hugo.Extended
Как видно на скриншоте Hugo установился последней версии и появился в списке установленных программ Windows (что меня приятно удивило).
PS C:\WINDOWS\system32> hugo version hugo v0.165.0-76a5e1880ab46688155b02e99bab9be2a6134492+extended windows/amd64 BuildDate=2026-08-12T14:26:28Z VendorInfo=gohugoio
Рекомендуемые расширения для VS Code:
- Hugo Language and Syntax Support (от vscode-hugo) — подсвечивает синтаксис шаблонов Hugo.
- Front Matter CMS — потрясающий плагин для VS Code, который превращает редактор в полноценную визуальную CMS (удобно управлять тегами, категориями и файлами прямо из интерфейса).
- (не ставлю) Markdown All in One — быстрые хоткеи для форматирования Markdown. Я предпочитаю для редактирования md файлов использовать Obsidian (бесплатную версию), очень удобно преобразует html в Markdown.
Создадим проект в Windows 11. Переходим в папку нашего проекта и создаем структуру Hugo:
cd C:\Projects\project_dnet hugo new site . --force
Тема Hextra подключается как Hugo Module или Git Submodule. Инициализируем Git и модуль (если git не установлен изучите Как установить GIT в Windows):
git init git submodule add https://github.com/imfing/hextra.git themes/hextra
Создание проекта
Перейди в каталог, где хочешь держать проект (мой проект называется vs_engine). Эта команда создаст структуру каталогов (content/, layouts/, static/, config и т.д.).
hugo new site vs_engine
cd vs_engine
Инициализируй Git (желательно сразу), что упростит дальнейшую работу, деплой и откат изменений.
git init git add . git commit -m "init"
Добавление темы
- Выбери тему на https://themes.gohugo.io для примера возьмем тему Ananke Gohugo Theme.
- Подключи её как submodule, то есть как внешний репозиторий и зафиксировать его как зависимость. Будет создана папка themes/doks, но это не обычная папка, а вложенный Git-репозиторий (там свой .git и своя история). Также в корне проекта появится файл .gitmodules, который говорит Git где лежит подмодуль и из какого репозитория он берётся.
cd /home/darkfire/vs_engine git submodule add https://github.com/theNewDynamic/gohugo-theme-ananke.git themes/ananke
- В корне проекта в hugo.toml (или hugo.yaml) пропиши тему, которую Hugo будет использовать при сборке:
echo "theme = 'ananke'" >> hugo.toml
Тема Hugo Book
Тема Book Introduction Hugo Book.
Откуда теперь берутся названия разделов? Их не нужно прописывать в . Названия и порядок задавай в _index.md соответствующего раздела. Например, content/ru/services/_index.md:
--- title: 'Софт и сервисы' weight: 1 ---
Если нужен короткий текст именно в меню, можно задать linkTitle.
Установка Book с готовым шаблоном сайта и нужной версией Hugo
#!/bin/bash set -e # --- Настройки --- PROJECT_NAME="project_book_latest_hugo" HUGO_VER="0.165.0" # ----------------- PROJECT_DIR="$HOME/$PROJECT_NAME" echo "1. Скачиваем Hugo v${HUGO_VER}..." mkdir -p "$PROJECT_DIR/bin" wget -q "https://github.com/gohugoio/hugo/releases/download/v${HUGO_VER}/hugo_extended_${HUGO_VER}_linux-amd64.tar.gz" -O /tmp/hugo.tar.gz tar -xzf /tmp/hugo.tar.gz -C "$PROJECT_DIR/bin" hugo chmod +x "$PROJECT_DIR/bin/hugo" rm -f /tmp/hugo.tar.gz echo "2. Настраиваем Git и тему..." cd "$PROJECT_DIR" git init git submodule add https://github.com/alex-shpak/hugo-book.git themes/hugo-book git add . git commit -m "Initial commit" echo "3. Копируем готовый шаблон..." cp -r themes/hugo-book/exampleSite/* . echo "Готово! Запуск проекта:" echo "cd $PROJECT_DIR && ./bin/hugo server -D"
Тема Hextra альтернатива Book
Hextra выглядит современнее Hugo Book и уже включает:
- мультиязычность;
- документацию и блог;
- breadcrumbs;
- sidebar и pagination;
- Mermaid и математические формулы;
- вкладки, карточки и callouts;
- тёмную тему;
- FlexSearch;
- SEO и Open Graph.
Тема Hextra активно развивается, но до сих пор имеет ряд недостатков:
- В текущем исходный код на 06.09.2026: переключатель перебирает все языки сайта. Если перевода текущей страницы нет, функция lang-link возвращает адрес главной страницы выбранного языка. Поэтому отсутствие перевода не убирает язык из списка. То есть та же самая проблема что и у Astro Starlight.
- FlexSearch остаётся браузерным поиском. Его можно заменить на Pagefind, но тогда преимущество «всё из коробки» частично исчезает.
Тема Relearn
Тема Relearn главный конкурент Book: больше готовых функций: Более развитая навигация и поиск, таксономии, печать разделов, включение файлов, много компонентов.
Что Relearn даёт сверх простой базы знаний
Полезные именно тебе возможности:
- Включение содержимого файлов: удобно для повторно используемых фрагментов инструкций и примеров конфигурации.
- Автоматические списки дочерних страниц: для оглавлений разделов.
- Печать целого раздела или сайта: например, подборки инструкций по настройке сервера.
- Поиск с подсветкой на странице, всплывающими результатами и отдельной страницей результатов.
- Настраиваемые меню, таксономии, карточки, вкладки, сворачиваемые блоки и список вложенных ресурсов.
Эти функции описаны в документации Relearn. По возможностям организации и чтения большого справочника он ближе к возможностям DokuWiki установка (Nginx + PHP-FPM или Apache), настройка и использование.
Тема PaperMod
Предустановленные CSS-переменные PaperMod. Тема использует стандартные CSS Variables для светлой и тёмной темы. Вы можете легко переопределить их в вашем assets/css/extended/custom.css:
/* Изменение палитры для тёмной темы (по умолчанию) */ :root { --gap: 24px; --content-gap: 20px; --nav-width: 1024px; --main-width: 720px; --header-height: 60px; --footer-height: 60px; --radius: 8px; --theme: rgb(29, 30, 32); --entry: rgb(37, 38, 40); --primary: rgb(218, 218, 219); --secondary: rgb(155, 156, 157); --tertiary: rgb(65, 66, 68); --content: rgb(196, 196, 197); --hljs-bg: rgb(46, 46, 51); --code-bg: rgb(55, 56, 62); --border: rgb(51, 51, 51); } /* Изменение палитры для светлой темы */ .list.light { --theme: rgb(255, 255, 255); --entry: rgb(255, 255, 255); --primary: rgb(30, 30, 30); --secondary: rgb(108, 108, 108); --tertiary: rgb(214, 214, 214); --content: rgb(50, 50, 50); --hljs-bg: rgb(28, 29, 33); --code-bg: rgb(245, 245, 245); --border: rgb(238, 238, 238); }
Создание первой страницы и запуск
Создай первый пост:
hugo new posts/first-post.md
Hugo создаст файл с front matter и draft: true; отредактируй его и поставь draft: false, чтобы пост был виден.
Запусти dev‑сервер. По умолчанию сайт откроется на http://localhost:1313, пересборка идет автоматически при изменении файлов. Ключ D позволяет показывать также черновики ваших постов.
hugo server -D
Для продакшен‑сборки запусти просто hugo. Готовый статический сайт окажется в каталоге public/, его уже можно заливать на VPS, Nginx, GitHub Pages и т.п.
Содержимое public/ можно спокойно удалять, это просто результат сборки, а не исходники. Обычно public/ не коммитят в Git (добавляют в .gitignore), а используют только как артефакт для деплоя.
Статические файлы
В Hugo все статические файлы должны лежать в папке static.
Мультиязычность
Мультиязычность i18n. Hugo берет значение из текущего языка (например, ru.toml). Если перевода для ключа в ru.toml нет, Hugo автоматически берет значение из языка по умолчанию (en.toml). Поэтому файл en.toml служит «базовым словарем» всего сайта.
В каком формате могут храниться языковые файлы i18n?
Hugo поддерживает 3 основных формата файлов в директории i18n/. Вы можете выбрать любой, Hugo определит его по расширению:
- TOML (i18n/en.toml, i18n/pt.toml) — Рекомендуемый. Идеален для проектов, где основной конфиг hugo.toml написан на TOML.
- YAML (i18n/en.yaml, i18n/pt.yaml). Очень чистый синтаксис без лишних скобок, удобен для чтения человеком.
- JSON (i18n/en.json, i18n/pt.json) Стандарт для web-разработки, удобно, если тексты переводов будут генерироваться скриптами или импортироваться из внешних систем.
{ "tld_domain": { "other": "Domain Zone" }, "tld_type": { "other": "Type" }, "tld_manager": { "other": "Registry Manager" } }
Поиск на статическом сайте через Fuse.js
Fuse.js — это лёгкий клиентский библиотечный движок для нечёткого поиска (fuzzy search). Он идеален для static-first архитектуры на Hugo, так как не требует backend-серверов или Node.js в runtime.
Принцип работы Fuse.js в Hugo:
- Генерация JSON-индекса: Hugo при сборке сайта генерирует единый компактный файл index.json.
- Загрузка через fetch: При открытии страницы браузер асинхронно скачивает индекс.
- Поиск в памяти: При вводе символов Fuse.js мгновенно ищет совпадения по массиву, учитывая опечатки, сходство строк и заданные веса полей.
- Динамический рендер: Поисковая выдача подставляется в DOM без перезагрузки страницы.
FAQ 1: Как работает обычный пост (hugo new posts/first.md)
Когда ты создаешь обычный пост, ты пишешь текст внутри файла (после —). У этого поста нет параметра layout.
Hugo действует так:
- Видит пост в папке posts.
- Ищет специальный шаблон. Не находит.
- Берет стандартный шаблон темы (themes/ananke/layouts/_default/single.html).
- Этот шаблон делает простую вещь: берет текст твоего поста и выводит его на экран.
Если же мы генерируем файлы, то там не будет текста. Если мы применим к ним стандартный шаблон (как для обычных постов), то Hugo просто выведет Заголовок и… пустую страницу. Именно поэтому в Python-скрипте мы добавили строчку: layout: "compare". Эта строчка говорит Hugo: "Не используй стандартный шаблон! Ищи специальный файл с именем compare.html".
Куда положить этот compare.html?
Hugo ищет шаблоны в строгом порядке. Если твой контент лежит в content/posts, то Hugo ищет шаблон в такой последовательности:
- layouts/posts/compare.html
- layouts/_default/compare.html (Запасной вариант).
Обычные посты (без layout: "compare") будут по-прежнему открываться через стандартный шаблон темы.
FAQ 2: Как создать robots.txt, ads.txt в Hugo
- Как добавить файл ads.txt или любой статический файл? Файл ads.txt необходим для борьбы с мошенничеством в сфере рекламы. Он показывает покупателям рекламы, что вы являетесь законным владельцем сайта и авторизуете определенных поставщиков (например, Google AdSense) продавать рекламу на вашем ресурсе.
Решение: Поскольку ads.txt — это статический текстовый файл, который не требует обработки Hugo, его проще всего поместить в папку static. Создайте файл в директории с нужным содержимым static/ads.txt. Как это работает: Любой файл, помещенный в папку static/, копируется Hugo как есть в корень папки public/.
- Как создать robots.txt в Hugo? Файл robots.txt нужен для того, чтобы сообщать поисковым роботам (Googlebot, Bingbot и т.д.), какие части вашего сайта они могут сканировать, а какие — нет. Hugo имеет встроенный шаблон для генерации robots.txt. По умолчанию этот файл:
- Разрешает сканировать весь сайт (Allow: /).
- Ссылается на ваш sitemap.xml.
В разных версиях Hugo файл robots.txt может генерироваться по разному, в версии hugo v0.152.2 мне пришлось создать файл layouts/index.robots.txt с содержимым
User-agent: * Allow: / Sitemap: {{ "sitemap.xml" | absURL }}
и в начало файла hugo.toml добавить настройки:
# ========================================================== # --- 1. НАСТРОЙКИ ВЫВОДА ФОРМАТОВ (RobotsTXT) --- # ========================================================== [mediaTypes] [mediaTypes."text/plain"] suffixes = ["txt"] delimiter = "" [outputFormats] [outputFormats.RobotsTXT] mediaType = "text/plain" baseName = "robots" isPlainText = true notRendering = false [outputs] home = ["HTML", "RSS", "RobotsTXT"] # ==========================================================
FAQ 3: Что такое Tailwind CSS? Сравнение: PaperMod vs. Tailwind CSS
Tailwind CSS — это utility‑first CSS‑фреймворк: вместо готовых компонентов он даёт кучу маленьких классов типа flex, mt-4, text-gray-700, из которых ты собираешь дизайн прямо в HTML. С Hugo он стыкуется как шаг сборки: Tailwind генерирует итоговый CSS (обычно через CLI/PostCSS), а Hugo подключает этот CSS как ресурс в шаблонах.
Hugo сам по себе не умеет «стилизовать», он просто собирает HTML; Tailwind подключается как отдельная стадия, которая из input.css и шаблонов Hugo собирает минимальный output.css.
| Критерий | PaperMod | Tailwind CSS (через Hugo Pipe) |
| Скорость запуска | 10/10 (установил и забыл) | 6/10 (нужна база верстки) |
| Гибкость дизайна | Низкая (сложно менять сетку) | Безграничная |
| Конверсия (CTR) | Средняя (похож на сотни сайтов) | Высокая (делаем кнопки и таблицы «как в Apple») |
| SEO (Core Web Vitals) | Отлично | Идеально (только нужный CSS) |
| Сложность правок | Мучение (перезапись CSS-файлов темы) | Легко (классы прямо в HTML/шаблонах) |
FAQ: Настройка внешних ссылок (Render Hooks) в Hugo: автоматическое добавление атрибутов nofollow _blank
Чтобы не прописывать атрибуты target="_blank" и rel="nofollow" вручную для каждой ссылки, в Hugo используются Render Hooks. Это позволяет писать обычный Markdown, а всю техническую работу переложить на движок сайта.
- Создайте файл в папке вашего проекта по пути: layouts/_default/_markup/render-link.html.
- Вставьте в него следующий код:
<<a href="{{ .Destination | safeURL }}"{{ with .Title }} title="{{ . }}"{{ end }}{{ if strings.HasPrefix .Destination "http" }} target="_blank" rel="noopener nofollow"{{ end }}>{{ .Text | safeHTML }}</a>
Почему это лучше, чем использовать прямой HTML-код в статьях? Использование Render Hooks дает три критических преимущества:
- Чистота контента: Ваш Markdown остается «человекочитаемым». Вместо громоздких тегов <a> вы пишете простую конструкцию [текст](url).
- SEO-безопасность: Вы гарантированно не забудете добавить nofollow к партнерской ссылке, что критично для сохранения веса сайта (Link Juice) и соответствия правилам Google E-E-A-T.
- Глобальный контроль: Если завтра вам понадобится убрать target="_blank" со всех ссылок, вам нужно будет изменить всего один файл, а не переправлять сотни статей.
Будут ли внутренние ссылки открываться в новом окне? Нет. Логика кода выше проверяет префикс ссылки. Если ссылка начинается с http (внешняя), Hugo добавит атрибуты для открытия в новом окне. Если это относительная ссылка (внутренняя, например /posts/my-article/), она откроется в той же вкладке, сохраняя стандартное поведение пользователя на сайте.
Нужно ли добавлять rel="noopener"? Да, при использовании target="_blank" добавление rel="noopener" является обязательным стандартом безопасности. Это предотвращает доступ открытой страницы к объекту window.opener вашей страницы, что защищает от фишинговых атак и улучшает производительность браузера.
FAQ: Подключение сложного JS и React к Hugo
Мнение о том, что «Hugo — это просто статика и туда нельзя вставить React» — это миф.
В Hugo есть мощный встроенный инструмент Hugo Pipes (который под капотом использует ESBuild). Вы спокойно можете вызывать и запускать внутри Hugo любой современный JavaScript/TypeScript, подключать библиотеки из npm и рендерить React-компоненты. Есть три способа использовать React/JS в Hugo:
- Простой React / Vue / JS прямо в Markdown-файлах (Shortcodes). Если вам нужно вставить интерактивный виджет (например, динамический калькулятор, фильтр или интерактивную таблицу) прямо внутрь статьи: Вы создаете обычный React-компонент (или чистый JS) и оборачиваете его в Hugo Shortcode (аналог шорткодов в WordPress или компонентов в MDX).
- Использование ESBuild (Встроено в Hugo из коробки). Вы можете положить свои .jsx / .tsx / .ts файлы в папку assets/js/, и Hugo сам автоматически соберет их, скомпилирует, минифицирует и подключит к сайту:
{{ $built := resources.Get "js/calculator.jsx" | js.Build }} <script src="{{ $built.RelPermalink }}"></script>
- Подключение через Widget / Web Components (Zero-Build React). Для легких реактивных виджетов можно использовать Preact или React через CDN / ES Modules или компилировать их в стандартные Web Components. Они встают в Hugo без настройки сложных сборщиков Webpack/Vite.
Рекомендуемые обзоры инструментов
Инновационный браузер с поддержкой ИИ
Бесконечные профили для арбитража
Надежное решение для мультиаккаунтинга
Лидер рынка для арбитражников