# Генератор статичних сайтів

## Що це таке

Генератор статичних сайтів — це інструмент збірки, який бере теку з вихідними
файлами, зазвичай сторінками, написаними в Markdown, і набір шаблонів та
перетворює їх на готовий вебсайт, що складається лише з файлів: HTML, таблиць
стилів, скриптів і зображень, які вебсервер віддає точно такими, якими вони є.
Назву часто скорочують до SSG, а слово «статичний» описує те, як результат
віддається, — ті самі байти кожному, хто запитує адресу, — а не те, як сторінка
поводиться, коли вже потрапила в браузер.

Протилежність йому — динамічний підхід системи керування вмістом чи
вебзастосунку, де програма на сервері збирає кожну сторінку в момент запиту,
зазвичай звертаючись до бази даних і заповнюючи шаблони. Генератор проганяє такі
самі шаблони по такому самому вмісту, але раз на кожну зміну, а не раз на кожен
візит, і залишає результат у теці, яку звичайний вебсервер, об'єктне сховище чи
мережа доставки вмісту може віддавати, не знаючи, як ці сторінки зроблено.

Hugo — один із таких генераторів статичних сайтів. Його документація представляє
його як генератор, написаний на Go, оптимізований для швидкості й розроблений
для гнучкості, що збирає цілий сайт за секунди, а часто й швидше. Звичайний цикл
— писати із запущеним вбудованим вебсервером Hugo, який перезбирає сайт після
кожної зміни й перезавантажує відкриті сторінки в браузері, а потім зібрати сайт
і розгорнути його на хостингу:

```sh
hugo server     # збирає, віддає й перезбирає після кожного збереження
hugo --minify   # записує готовий сайт у public/
```

## Чому це важливо

Цей вибір — про те, коли виконується робота. Генератор переносить її з моменту
запиту на етап збірки, і майже все інше випливає саме з цього.

Віддати файл — чи не найдешевше, що робить вебсервер, тож згенерований сайт
відповідає швидко й може працювати на дуже малій машині, а оскільки кожен
відвідувач адреси отримує ті самі байти, кешування просте. Коли за сторінками
немає коду застосунку чи бази даних, захищати й оновлювати доводиться набагато
менше. Результат — це тека, тож переїзд на інший хостинг зводиться до копіювання
файлів, а вихідні файли лежать у системі контролю версій, де кожну зміну кожної
сторінки можна переглянути й простежити.

Витрати походять звідти ж. Кожна зміна, навіть виправлена одруківка, означає
нову збірку й нове розгортання, тож швидкість збірки важить тим більше, чим
більше сторінок. Усе, що залежить від того, хто запитує, як-от пошук, коментарі,
вхід до облікового запису чи форма, що зберігає отримане, потребує коду в
браузері, окремого сервісу або способу вирішити це під час збірки, бо на сервері
немає програми, яка б це зробила. Між збірками час стоїть на місці: Hugo за
замовчуванням пропускає сторінку з датою в майбутньому, тож сторінка,
запланована на понеділок, з'являється з першою збіркою в понеділок або пізніше.
Навіть переспрямування змінюють форму. Коли немає програми, яка надіслала б
HTTP-переспрямування, Hugo для переміщеної сторінки типово кладе за старою
адресою невеликий HTML-файл, що відправляє браузер далі, — підхід, який
документація називає переносним між усіма хостинг-провайдерами.

## Як це виглядає на практиці

Цей сайт зібрано за допомогою генератора статичних сайтів. [Сторінка
подяк](/uk/credits/) називає Hugo генератором статичних сайтів і приписує йому
шаблони, таксономії, усі мови та стрічки. Про те, що потрапляє в браузер, вона
каже, що HTML повністю готовий ще до того, як хтось його попросить: кожна
сторінка лежить на диску файлом, а не складається з шаблону під кожен запит.
Навіть вигляд визначається під час збірки: світла тема отримує одну зі своїх
стін, коли збирається сторінка, тож з кожною публікацією сайт виглядає інакше.
Збірку не віддано на сторонній сервіс: обов'язкові перевірки якості запускаються
на машині, де пишеться сайт, будь-яке зауваження інструмента там рахується як
помилка, а в жовтні 2026 року збиралося 2 268 сторінок. Їх віддає одноядерний
сервер з 512 МБ пам'яті, де вебсервер ділить ту саму теку з файлами з трьома
іншими сервісами, що відповідають за сайт, тож одне розгортання доходить до всіх
чотирьох.

[Запис у портфоліо про те, як цей сайт збудовано на Hugo](/uk/portfolio/built-a-multilingual-static-site-in-hugo-126/)
пояснює, чому так. Три мови, нуль витрат на роботу й відвідувачі, яких не
передають нікому іншому, відсіяли майже всі системи керування вмістом, бо
запущений бекенд вимагає захисту, оновлень і грошей, а ще пояснень на сторінці
конфіденційності. Сайт має 108 файлів шаблонів, 53 з них — часткові шаблони,
публікує кожну сторінку в чотирьох поданнях з одного дерева вмісту й збирає це
дерево ще сім разів для тематичних субдоменів, вказуючи генераторові іншу теку з
вмістом. Можливості додаються під час збірки, а не в браузері, і запис прямо
називає ціну: усе інтерактивне треба вирішити під час збірки або не вирішувати
взагалі, тому пошуковий індекс прорахували й відклали, замість того щоб
випустити.

## Де виникають проблеми

**Видалена сторінка лишається в мережі.** Сторінку, прибрану з вихідних файлів,
досі віддають за старою адресою, і пошукові системи й далі її знаходять. Hugo не
очищає теку з результатом перед збіркою: наявні файли перезаписуються, але
ніколи не видаляються, тож у `public/` можуть лишатися сторінки з попередніх
збірок, зокрема чернетки й сторінки з минулим терміном дії, і все, що копіює цю
теку на сервер, копіює і їх. Кеш `resources/` у Hugo має споріднену проблему:
правила дизайну цього сайту попереджають, що він може віддати застарілий
CSS-бандл, коли змінився лише вихідний CSS. Збирайте в чисту теку, з прапорцем
Hugo `--cleanDestinationDir` або власним кроком видалення; збірка цього сайту
прибирає і `public/`, і `resources/`, перш ніж почати.

**Готова сторінка так і не з'являється.** Допис написано, закомічено й
розгорнуто, збірка повідомляє про успіх, а сторінки для нього на сайті немає. За
замовчуванням Hugo пропускає вміст, позначений як чернетка, вміст, дата або дата
публікації якого в майбутньому, і вміст, термін дії якого минув, і все це не
вважається помилкою. Досить дати, набраної на день наперед. Спершу перевірте ці
чотири поля, лишіть `--buildDrafts`, `--buildFuture` і `--buildExpired` для
попередніх переглядів, а для запланованої сторінки подбайте про збірку після її
дати.

**Кожна сторінка заявляє, що змінилася водночас.** Карта сайту дає майже кожній
адресі той самий час останньої зміни, а це каже пошуковому роботові, що змінився
весь сайт, і мовчить про те, які сторінки змінилися насправді. Генератор мусить
десь брати дату зміни кожної сторінки, і власна позначка часу файлу — хибне
джерело, коли якийсь крок перезаписує файли, вміст яких лишається тим самим.
Конфігурація цього сайту фіксує, що крок синхронізації перезаписує всі 189
файлів вмісту під час кожного запуску, тож 172 зі 176 адрес у карті сайту мали
одну позначку часу. Беріть дату із системи контролю версій: Hugo читає дату
останньої Git-ревізії файлу, коли ввімкнено `enableGitInfo`, а повторна
синхронізація, яка дає ідентичні байти, не створює коміту, тож синхронізація
після місяця правок зачепила 8 із 186 файлів.

**Назовні потрапляють файли, які ніхто не збирався публікувати.** Будь-хто, хто
вгадає назву, може завантажити файл, що перелічує інші файли. Генератор публікує
все, що лежить у теках, які він читає, за винятком того, що прибирає правило
виключення, а правило, яке сягає не кожної теки, лишає решту відкритою.
Конфігурація цього сайту фіксує, що загальний список ігнорування сайту не діяв
на змонтовану теку модуля: збірка опублікувала всі шість файлів `.DS_Store`, які
Finder у macOS залишив в icons/, images/ і webmanifest/, на кожному хості, і
кожен перелічував назви поруч із собою, тож той, що в images/, назвав теку, яку
сайт приховує. Фільтр, якому бракувало одного пробілу після `!`, одного разу
натомість виключив усі зображення в монтуванні. Задавайте виключення на кожному
монтуванні, що публікує, а потім перевіряйте зібраний результат на файли, яким
там не місце; дві перевірки цього сайту зупиняють збірку, що віддає такий файл.

## Що почитати далі

- [Hugo: Introduction](https://gohugo.io/about/introduction/) — що таке Hugo,
  для чого його використовують і як проходить цикл від написання до збірки й
  розгортання.
- [Hugo: Basic usage](https://gohugo.io/getting-started/usage/) — як зібрати
  сайт і запустити сервер, чому `public/` зберігає старі файли і який вміст
  збірка пропускає.
- [Hugo: Configure front matter](https://gohugo.io/configuration/front-matter/)
  — як Hugo вибирає дати сторінки, зокрема токени `:git` і `:fileModTime`.
- [Hugo: Configure modules](https://gohugo.io/configuration/module/) —
  монтування, фільтр `files` для кожного з них і правило, за яким оголошене
  монтування прибирає типове.
- [Hugo: URL management](https://gohugo.io/content-management/urls/) —
  псевдоніми й файли переспрямування, які статичний хостинг віддає замість
  серверного переспрямування.

<https://engineer.company/uk/glossary/ssg/>
