Featured image of post Ставимо Hugo

Ставимо Hugo

Покроковий гайд з розгортання блогу на Hugo, налаштування теми Stack та організації конфігурації

Колись, у старі добрі часи, писав трохи технічних статей на платформі Blogger - було прикольно, й часом корисно повернутися в часі й повторити якийсь сетап.

І ось @Schistos почав свої сетапи описувати подібним чином, накрило ностальгією й пішов досліджувати тему, що зараз актуальне. Ну й знайшов кілька проєктів з генерації статичних сайтів, проте найбільше до душі припав Hugo, ось ви на нього зараз й дивитеся 😉

Як це працює?

📝 Примітка

Hugo - це статичний генератор сайтів. Ви пишете контент у Markdown-файлах, а Hugo перетворює їх на готові HTML/CSS/JS сторінки під час збірки. Це забезпечує максимальну швидкість завантаження та безпеку, оскільки на сервері немає бази даних чи активного бекенду.

Це зручно тримати в git-репозиторії й налаштувати CI/CD для збірки й публікації в GitHub/GitLab Pages, чим ми й займемося.

Вибір теми

Для початку йдемо на themes.gohugo.io й обираємо те, що подобається. Я, після кількох годин перегляду усіх можливих і неможливих тем, зупинив свій вибір на темі Stack. Йдемо на GitHub теми й у README.md бачимо, що автор створив шаблон репозиторію, який можна просто використати для швидкого розгортання, проте ми не шукаємо простих шляхів, тому будемо робити все вручну. Хостити я збираюся не на GitHub, а на GitLab, тому дещо доведеться адаптувати під себе у будь-якому разі.

Встановлення Hugo

Ставимо Hugo і Git:

1
sudo pacman -Sy hugo git

І перевіряємо чи все ок:

1
2
hugo version
hugo v0.165.0+extended+withdeploy linux/amd64 BuildDate=unknown

Створюємо проєкт

1
hugo new project blog.hardfault.win

Нам дає трішки підказок щодо того що робити далі. Глянемо що вже є:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
cd blog.hardfault.win && hugo server -D

Watching for changes in archetypes, assets, content, data, i18n, layouts, static
Watching for config changes in hugo.toml
Start building sites …
hugo v0.165.0+extended+withdeploy linux/amd64 BuildDate=unknown

WARN  found no layout file for "html" for kind "home": You should create a template file which matches Hugo Layouts Lookup Rules for this combination.
WARN  found no layout file for "html" for kind "taxonomy": You should create a template file which matches Hugo Layouts Lookup Rules for this combination.

                  │ EN
──────────────────┼────
 Pages            │  4
 Paginator pages  │  0
 Non-page files   │  0
 Static files     │  0
 Processed images │  0
 Aliases          │  0
 Cleaned          │  0

Built in 2 ms
Environment: "development"
Serving pages from disk
Running in Fast Render Mode. For full rebuilds on change: hugo server --disableFastRender
Web Server is available at http://localhost:1313/ (bind address 127.0.0.1)
Press Ctrl+C to stop

Отже, бачимо список директорій, за якими Hugo відстежує зміни, і одразу ж попередження про те, що він не має шаблонів для необхідних сторінок - це треба виправити.

Встановлюємо тему

Hugo використовує Go modules для керування залежностями, тому перетворимо наш проєкт на Go модуль:

1
2
3
4
hugo mod init blog.hardfault.win
go: creating new go.mod: module blog.hardfault.win
hugo: to add module requirements and sums:
        hugo mod tidy

Переглянемо його:

1
2
3
module blog.hardfault.win

go 1.26.6

Далі - додаємо залежність від нашої теми:

1
2
3
4
5
# ...

[module]
  [[module.imports]]
    path = "github.com/CaiJimmy/hugo-theme-stack/v4"

Перезапускаємо наш сервер:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
hugo server -D
Watching for changes in archetypes, assets, content, data, i18n, layouts, static
Watching for config changes in hugo.toml, go.mod
Start building sites …
hugo v0.165.0+extended+withdeploy linux/amd64 BuildDate=unknown


                  │ EN
──────────────────┼────
 Pages            │  8
 Paginator pages  │  0
 Non-page files   │  0
 Static files     │  0
 Processed images │  0
 Aliases          │  3
 Cleaned          │  0

Built in 33 ms
Environment: "development"
Serving pages from disk
Running in Fast Render Mode. For full rebuilds on change: hugo server --disableFastRender
Web Server is available at http://localhost:1313/ (bind address 127.0.0.1)
Press Ctrl+C to stop

Warning-ів немає - можна переглянути у браузері:

Screenshot1

Поки не густо, але вже працює. Проглянемо поточний граф залежностей:

1
2
hugo mod graph
blog.hardfault.win github.com/CaiJimmy/hugo-theme-stack/[email protected]

Підлаштування теми під себе

💡 Порада

Щоб зручніше переглядати вихідний код теми та вносити в нього правки (якщо це потрібно), використовуйте команду hugo mod vendor. Вона завантажить копію модуля в локальну директорію _vendor, що дозволить шукати по коду теми за допомогою IDE.

1
hugo mod vendor

Це створить директорію _vendor у нашому проєкті:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
tree -d _vendor -L 5
_vendor
└── github.com
    └── CaiJimmy
        └── hugo-theme-stack
            └── v4
                ├── archetypes
                ├── assets
                ├── config
                ├── data
                ├── i18n
                └── layouts

11 directories

Скопіюємо й перглянемо конфіги з теми в проєкт:

1
cp -r _vendor/github.com/CaiJimmy/hugo-theme-stack/v4/config .
1
2
3
4
5
6
7
tree config
config
└── _default
    ├── module.toml
    └── params.toml

2 directories, 2 files

module.toml - тут тільки залежності від Hugo, а ось в params.toml знаходяться всі основні налаштування теми.

📌 Важливо

Щоб конфігурації не були розкидані по всьому проєкту, краще перемістити кореневий hugo.toml до інших конфігів у config/_default/ та розбити його на тематичні файли.

Переміщуємо файл:

1
mv hugo.toml config/_default/

І наводимо ладу: import із config.toml перемістимо в module.toml, змінимо імена і т.п. Отримуємо:

1
2
3
baseURL = 'https://hardfault.win/'
locale = 'en'
title = 'HardFault.win'
1
2
3
4
5
6
[hugoVersion]
    extended = true
    min      = "0.157.0"

[imports]
    path = "github.com/CaiJimmy/hugo-theme-stack/v4"

Створимо конфіг для бокового меню:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
[[social]]
  identifier = "github"
  name       = "GitHub"
  url        = "https://github.com/elektro-NIK"
  [social.params]
    icon = "brand-github"

[[social]]
  identifier = "gitlab"
  name       = "GitLab"
  url        = "https://gitlab.com/elektro.NIK"
  [social.params]
    icon = "brand-gitlab"

[[social]]
  identifier = "linkedin"
  name       = "LinkedIn"
  url        = "https://www.linkedin.com/in/elektro-nik"
  [social.params]
    icon = "brand-linkedin"


[[main]]
  identifier = "home"
  name = "Home"
  url = "/"
  weight     = 10
  [main.params]
    icon = "home"

[[main]]
  identifier = "about"
  name       = "About"
  url        = "/about/"
  weight     = 20
  [main.params]
    icon = "user"

[[main]]
  identifier = "archives"
  name       = "Archives"
  url        = "/archives/"
  weight     = 30
  [main.params]
    icon = "archives"

[[main]]
  identifier = "search"
  name       = "Search"
  url        = "/search/"
  weight     = 40
  [main.params]
    icon = "search"

[[main]]
  identifier = "links"
  name       = "Links"
  url        = "/links/"
  weight     = 50
  [main.params]
    icon = "link"

І покладемо іконки, яких немає в темі:

1
2
3
4
5
6
tree assets/icons 
assets/icons
├── brand-gitlab.svg
└── brand-linkedin.svg

1 directory, 2 files

Screenshot2

Всі посилання ведуть на 404, проте це вже щось :) Додамо сторінки, щоб бачити їхній функціонал:

1
hugo new content content/page/about/index.md
1
hugo new content content/page/archives/index.md
1
hugo new content content/page/links/index.md
1
hugo new content content/page/search/index.md

Редагуємо файли:

1
2
3
4
5
+++
date = '2026-01-01T00:00:00+00:00'
draft = false
title = 'About'
+++
1
2
3
4
5
6
+++
date = '2026-01-01T00:00:00+00:00'
draft = false
title = 'Archives'
layout = "archives"
+++
1
2
3
4
5
+++
date = '2026-01-01T00:00:00+00:00'
draft = false
title = 'Links'
+++
1
2
3
4
5
6
7
8
+++
date = '2026-01-01T00:00:00+00:00'
draft = false
title = 'Search'
type = "page"
layout = "search"
outputs = ["html", "json"]
+++

Додамо аватар й favicon:

1
2
3
4
5
6
tree assets/img 
assets/img
├── avatar.png
└── favicon.png

1 directory, 2 files
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
# ...

favicon = "img/favicon.png"

# ...

[sidebar]
    compact  = false
    avatar   = "img/avatar.png"
    emoji    = "🦀"
    subtitle = "Cortex-M panics, but we don't"

# ...

І створимо тестову публікацію:

1
hugo new content content/post/hello_world/index.md
1
2
3
4
5
6
7
## Hello

World

### Test

text

Цим вже можна користуватися, а в наступній частині ми займемося підключенням багатомовності.

Screenshot3 Screenshot4 Screenshot5 Screenshot6

Шпаргалка по конфігурації

ФайлПризначення
hugo.tomlОсновні налаштування сайту (baseURL, title, locale)
params.tomlНалаштування теми Stack (Sidebar, Footer, Cookies тощо)
module.tomlКерування версією Hugo та імпорт теми як модуля
menu.tomlСтруктура навігації та соцмереж у боковій панелі
languages.tomlНалаштування багатомовності (якщо використовується)
Licensed under CC BY-NC-SA 4.0
System Status: Running (0 HardFaults in last 24h) | Compiled with -Os
Створено з Hugo
Тема Stack, дизайн Jimmy