結論

Hugo(ヒューゴ)は、Markdown で書いた記事とテンプレートから、HTML だけのWebサイトを一度に書き出す静的サイトジェネレーターです。Go 言語で作られた1つの実行ファイルで動き、hugo new site→記事を書く→hugo server で確かめる→hugo で書き出す、の4段で使えます。

この記事でわかること

  • インストールから公開用ファイルまでの手順と、各コマンドの実際の出力
  • テーマの入れ方と、Hugo の版が合わないときに出るエラーの原文
  • 記事1,000本・1万本のビルド時間と、テンプレート1行で半分になった実測

2026年10月29日更新|Hugo 0.123.7(Ubuntu 24.04 の .deb)で実行確認・最新版 v0.169.0 は公式で確認

Hugo は「記事(Markdown)」「見た目(テンプレート・テーマ)」「設定(hugo.toml)」の3つを読み、public フォルダーに HTML・CSS・画像・RSS・サイトマップを書き出します。あとはそのフォルダーを置くだけで公開でき、サーバーでプログラムを動かす必要がありません。

flowchart TD
    A[記事・テンプレート・設定] --> H[hugo コマンド]
    H --> P[public フォルダー<br>HTML・CSS・RSS]
    P --> S[静的ホスティングに置く]

よく調べられることの答えを先にまとめます。

知りたいこと 答え 詳しい節
Hugo とは Go 製の静的サイトジェネレーター。Markdown から HTML を書き出す Hugoとは
Hugo のインストール Mac は brew、Windows は winget、Linux は公式の .deb か tar.gz インストールと版の確かめ方
Hugo の使い方(最初の4コマンド) new site → new content → server → hugo 使い方①・②
Hugo のテーマの入れ方 themes/ に置いて hugo.toml に theme = '名前' テーマの入れ方
テーマを入れたらエラーが出た 多くは Hugo の版が足りないことが原因。テーマの最低版を見る テーマの入れ方
記事が表示されない draft = true か、日付が未来。-D・-F で確かめる 使い方②
ビルドの速さ 手元の2コアで記事1,000本が約0.8秒、1万本が約16秒 ビルド時間を実測
Astro・Next.js との違い Hugo は Node.js も JavaScript も要らず、書き出し専用 違い(判断表)
どこで公開するか GitHub Pages・Netlify・Cloudflare など静的ホスティング ビルドして公開する

確認環境:Ubuntu 24.04.5 LTS(Intel Xeon 2.10GHz・2 vCPU・メモリ 7.9GB、ほかの処理と同居)の上で、Ubuntu の公式リポジトリの hugo 0.123.7-1ubuntu0.3(extended)を apt-get download で取得し、依存する libsass1 3.6.5 とともに作業用のフォルダーへ展開して実行しました(システムには入れていません)。hugo new site・hugo new content・hugo server(127.0.0.1 の自分のポート)・hugo・hugo list・--templateMetrics の出力、自作の最小テーマ、テーマ Ananke の4つの版(git で取得)との組み合わせ、記事1,000本・5,000本・1万本の自動生成とビルド時間、エラー14種類を手元で確かめています。応答は curl 8.5.0 で見ました。最新版 v0.169.0(2026年10月27日公開)は GitHub のリリースページで確かめ、手元では動かしていません。v0.146.0 以降のテンプレートの新しい置き場所、Mac・Windows のインストール、ホスティング先、エディションの違いは公式ドキュメント(gohugo.io)で確かめました。図は mermaid で描画を確かめています(確認日 2026年10月29日)。

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「Hugoとは・使い方|テーマ自作と1万記事のビルド実測・エラー原文」

Hugoとは(静的サイトジェネレーターの仕組み)

この節では、Hugo が何をする道具で、WordPress のような仕組みと何が違うのかが分かります。

Hugo は、サイトを「見に来た時」ではなく「公開する前」に全ページを HTML にしておく道具です。このような道具を静的サイトジェネレーター(SSG:Static Site Generator)と呼びます。Hugo は Go 言語で書かれたオープンソース(Apache License 2.0)のソフトで、配布物は実行ファイル1つです。Node.js や Ruby などの実行環境を別に入れずに動きます。

静的サイト(Hugo)

公開前に全ページを HTML にして置いておく

サーバーはファイルを返すだけ。DB もプログラムも動かない

速く、攻撃される入口が少なく、置き場所の費用が安い

動的サイト(WordPress など)

アクセスのたびに PHP が DB を読んで HTML を作る

管理画面から誰でも記事を書ける

ログイン・コメント・検索などをサーバー側で処理できる

Hugo が向くのは、ブログ・企業サイト・製品ドキュメント・ポートフォリオのように、読む人ごとに中身が変わらないページです。問い合わせフォームやコメントのようにサーバー側の処理が要る部分は、外部のサービスや別の API と組み合わせます。

1速い

ビルドが速いことで知られる。手元の2コアでも、記事1,000本のサイトを1秒前後で書き出した。

2単体で動く

実行ファイル1つで、開発用サーバー・画像の縮小・Sass(extended 版)・RSS・サイトマップまで入っている。

3Markdown で書く

記事はテキストファイルなので Git で履歴を残せる。プルリクエストで記事をレビューする運用に向く。

苦手なところもあります。テンプレートは Go の text/template({{ }} で囲む書き方)で、HTML と JavaScript だけで書ける道具に比べると最初に覚えることが多めです。また、記事を書く人も Markdown とフォルダーの決まりを知っている必要があり、管理画面はありません。

Hugoのインストールと版の確かめ方(Mac・Windows・Linux)

この節では、OS ごとのインストールの方法と、standard 版・extended 版の選び方、版の確かめ方が分かります。

OS の標準のパッケージ管理で入れるのが簡単ですが、最新の版とは限らないため、入れたら必ず hugo version で版を見ます。公式ドキュメントに載っている方法は次のとおりです(Mac・Windows は手元で動かせないため、公式の記載だけを載せています)。

OS コマンド(公式) 入る版
Mac(Homebrew) brew install hugo extended/deploy
Mac(MacPorts) sudo port install hugo extended
Windows(WinGet) winget install -e --id Hugo.Hugo.Extended extended
Windows(Chocolatey・Scoop) choco install hugo-extended・scoop install hugo-extended extended
Linux(Snap) sudo snap install hugo extended
Debian・Ubuntu sudo apt install hugo extended(版はディストリビューション次第)
全OS共通 GitHub のリリースページからアーカイブ・.deb を取得 4種類から選ぶ

公式ドキュメントは、リポジトリのパッケージについて「提供される版は最新とは限らない」と書いています。手元の Ubuntu 24.04 では、リポジトリの版は次のとおりで、2026年10月29日時点の最新 v0.169.0 からマイナー版で46前の版でした。

$ apt-cache policy hugo
hugo:
  Installed: (none)
  Candidate: 0.123.7-1ubuntu0.3

$ hugo version
hugo v0.123.7+extended linux/amd64 BuildDate=2025-07-18T03:41:49Z VendorInfo=ubuntu:0.123.7-1ubuntu0.3

Snap 版はサイトのフォルダーをホームかリムーバブルメディアに置く必要がある、と公式に注意書きがあります。Windows のパッケージ管理はどれも自動では更新されない、とも書かれています。

standard・extended・deploy の違い

エディション できること 選ぶ場面
standard 基本の機能すべて 迷ったらこれ(公式の案内)
deploy 加えて Google Cloud Storage・AWS S3・Azure Storage へ直接デプロイ hugo deploy を使う
extended 加えて LibSass で Sass(SCSS)を CSS にする テーマが SCSS を使う
extended/deploy 上の両方 両方使う

公式は「追加の機能が要らなければ standard を使う」と案内しています。なお、内蔵の LibSass は v0.153.0 で非推奨になり、将来の版で削除される予定で、Sass には Dart Sass が推奨されています。テーマの README に「extended が必要」とあれば extended を選びます。手元の版の中身は hugo env で見られます。

$ hugo env
hugo v0.123.7+extended linux/amd64 BuildDate=2025-07-18T03:41:49Z VendorInfo=ubuntu:0.123.7-1ubuntu0.3
GOOS="linux"
GOARCH="amd64"
GOVERSION="go1.22.2"
github.com/sass/libsass="3.6.5"
github.com/webmproject/libwebp="v1.3.2"

Hugoの使い方① hugo new siteでサイトを作る(フォルダー構成)

この節では、サイトのひな形を作るコマンドと、できあがるフォルダーそれぞれの役割が分かります。

最初に hugo new site 名前 で、空のサイトのひな形を作ります。手元の 0.123.7 で実行すると、次の案内が出ました。

$ hugo new site mysite
Congratulations! Your new Hugo site was created in /dev/shm/t87/mysite.

Just a few more steps...

1. Change the current directory to /dev/shm/t87/mysite.
2. Create or install a theme:
   - Create a new theme with the command "hugo new theme <THEMENAME>"
   - Install a theme from https://themes.gohugo.io/
3. Edit hugo.toml, setting the "theme" property to the theme name.
4. Create new content with the command "hugo new content <SECTIONNAME>/<FILENAME>.<FORMAT>".
5. Start the embedded web server with the command "hugo server --buildDrafts".

最新のドキュメント(v0.169.0 時点)のクイックスタートは、同じ操作を hugo new project quickstart と書いています。手元の 0.123.7 には new project の書き方がないため、版に合わせて読み替えます。

できたもの 入れるもの メモ
hugo.toml サイト全体の設定(URL・題名・テーマ) yaml・json でも書ける。以前の版は config.toml
content/ 記事の Markdown フォルダー名がそのまま URL とセクションになる
layouts/ サイト独自のテンプレート テーマより優先される
themes/ テーマ(テンプレート一式) git の submodule で入れることが多い
static/ そのまま公開するファイル(favicon・画像) public/ の直下にコピーされる
assets/ 加工してから使うファイル(SCSS・JS・画像) テンプレートから縮小・結合する
archetypes/ 新しい記事のひな形 hugo new content で使われる
data/・i18n/ テンプレートから読むデータ・翻訳 使わなければ空のまま

作った直後の hugo.toml は3行だけです。日本語のサイトなら、少なくとも languageCode と title、公開先が決まったら baseURL を書き換えます。

baseURL = 'https://example.org/'
languageCode = 'en-us'
title = 'My New Hugo Site'

テーマを入れずにそのまま hugo を実行すると、エラーではなく警告が3行出て、HTML は1枚も作られませんでした。できたのは RSS とサイトマップだけです。

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.
WARN  found no layout file for "html" for kind "section": You should create a template file which matches Hugo Layouts Lookup Rules for this combination.

                   | EN
-------------------+-----
  Pages            |  5
...
Total in 7 ms

「画面が真っ白」「index.html ができない」のいちばん多い原因は、テーマ(テンプレート)が無いことです。Hugo は記事を HTML にする「型」を持っていないため、テーマを入れるか、自分でテンプレートを書きます。

Hugoの使い方② 記事を書く(フロントマター・下書き・予約投稿)

この節では、記事ファイルの作り方と、先頭に書く設定(フロントマター)、記事が表示されないときの確かめ方が分かります。

記事は hugo new content posts/ファイル名.md で作ります。archetypes/default.md がひな形になり、題名と日時が入ったファイルができます。

$ hugo new content posts/first-post.md
Content "/dev/shm/t87/mysite/content/posts/first-post.md" created

$ cat content/posts/first-post.md
+++
title = 'First Post'
date = 2026-10-30T05:37:43+09:00
draft = true
+++

先頭の +++ で囲んだ部分がフロントマター(記事ごとの設定)です。区切りの記号で書き方が決まります。

形式 区切り 例
TOML +++ title = 'はじめての記事'
YAML --- title: "はじめての記事"
JSON { } "title": "はじめての記事"

手元で使った記事の例です。TOML で書き、タグ・カテゴリー・説明文を付け、本文ではショートコード(後の節)を使っています。

+++
title = 'はじめての記事'
date = 2026-10-29T10:00:00+09:00
draft = false
tags = ['hugo', '入門']
categories = ['お知らせ']
description = 'Hugoで書いた最初の記事です。'
+++

Hugoで最初の記事を書きました。Markdownで書いた本文が、テーマのテンプレートに流し込まれてHTMLになります。

{{< note type="warn" >}}
**ショートコード**の中でも Markdown が使えます。
{{< /note >}}

次の記事は[2本目]({{< ref "second.md" >}})です。

よく使うフロントマターの項目

項目 意味 メモ
title・date 題名と日付 一覧の並び順にも使われる
draft true なら下書き -D(--buildDrafts)を付けたときだけ出る
publishDate・expiryDate 公開日・公開終了日 未来の公開日は -F、期限切れは -E で出る
lastmod 最終更新日 サイトマップの lastmod に使われる
slug・url・aliases URL の末尾・URL 全体・転送元 aliases は以前の URL からの転送ページを作る
tags・categories 分類(タクソノミー) 一覧ページが自動でできる
description・summary 説明文・要約 description は meta 要素などに使う
weight・params・cascade 並び順・独自の値・子ページへの継承 独自の項目は params の下に置く(公式)

記事が出ないときは hugo list で確かめる

書いたのに出てこない記事は、ほとんどが「下書き」か「日付が未来」です。手元で、下書きの記事(draft = true)と、日付を 2026年12月1日にした記事を置いて確かめました。hugo list で一覧にすると、どちらの理由かがすぐ分かります。

$ hugo list drafts
path,slug,title,date,expiryDate,publishDate,draft,permalink
content/posts/draft.md,,下書きの記事,2026-10-29T13:00:00+09:00,0001-01-01T00:00:00Z,2026-10-29T13:00:00+09:00,true,https://example.com/posts/draft/

$ hugo list future
path,slug,title,date,expiryDate,publishDate,draft,permalink
content/posts/future.md,,予約投稿の記事,2026-12-01T09:00:00+09:00,0001-01-01T00:00:00Z,2026-12-01T09:00:00+09:00,false,https://example.com/posts/future/
ビルドの仕方 Pages posts/ にできた記事
hugo 21 hello・second
hugo server -D 22 hello・second・draft
hugo -D -F 23 hello・second・draft・future

予約投稿の記事は、日付を過ぎたあとにもう一度ビルドしたときに出ます。Hugo は時間がたっても自分では動かないため、予約投稿をするなら、CI で毎日ビルドするなどの仕組みを別に用意します。

記事のひな形は archetypes/ に「セクション名.md」を置くと、そのセクション用になります。手元で archetypes/posts.md にタグ・カテゴリー・説明文の欄を足すと、hugo new content posts/my-third-post.md で作った記事に、それらの空欄が最初から入りました。

hugo serverで確認する(127.0.0.1・ライブリロード)

この節では、書いた記事をブラウザで確かめる開発用サーバーの使い方と、保存してから画面に反映されるまでの流れが分かります。

hugo server は、ビルドしてからファイルの変更を見張り、保存するたびに作り直してブラウザを自動で再読み込みします。公式ドキュメントでは、待ち受けの既定は 127.0.0.1、ポートは 1313 です。手元ではほかの作業とぶつからないよう、ポートを指定して起動しました。

$ hugo server -D --bind 127.0.0.1 --port 48787 --baseURL http://127.0.0.1:48787/
Watching for changes in /dev/shm/t87/blog/{archetypes,assets,content,data,i18n,layouts,static,themes}
Watching for config changes in /dev/shm/t87/blog/hugo.toml
Start building sites …
hugo v0.123.7+extended linux/amd64 BuildDate=2025-07-18T03:41:49Z VendorInfo=ubuntu:0.123.7-1ubuntu0.3

                   | EN
-------------------+-----
  Pages            | 22
  ...
Built in 22 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://127.0.0.1:48787/ (bind address 127.0.0.1)
Press Ctrl+C to stop

curl で開くと、<head> の先頭にライブリロード用のスクリプトが差し込まれていました。hugo で書き出したファイルには入りません。

$ curl -i http://127.0.0.1:48787/posts/hello/
HTTP/1.1 200 OK
Content-Length: 2137
Content-Type: text/html; charset=utf-8

<!DOCTYPE html>
<html lang="ja">
<head><script src="/livereload.js?mindelay=10&amp;v=2&amp;port=48787&amp;path=livereload" data-no-instant defer></script>

記事の1文を書き換えて保存すると、サーバーのログに次の行が出て、3ミリ秒で作り直されました。直後に curl で開くと、書き換えた文になっていました。

Change detected, rebuilding site (#1).
2026-10-30 05:39:09.213 +0900
Source changed /posts/hello.md
Total in 3 ms
1

下書きも見る

hugo server -D。draft = true の記事も出す。

本番のビルドには付けない

2

ポートを変える

--port 8080。使用中のポートを指定すると起動に失敗する。

既定は 1313

3

スマホから見る

--bind 0.0.0.0 --baseURL http://PCのIP:1313/。同じ LAN の端末から開ける。

社外の回線では使わない

4

全部作り直す

--disableFastRender。一部だけ反映されない時に付ける。

止めるのは Ctrl+C

公式は hugo server を「機能の限られた Web サーバー」と説明しています。確認のための道具で、公開には hugo で書き出したファイルを Web サーバーやホスティングに置きます。

Hugoのテーマの入れ方と、版が合わないときのエラー

この節では、テーマを入れる手順と、テーマが求める Hugo の版より手元の版が低いときに何が起きるかが、実際のエラーで分かります。

テーマは themes/ の下にフォルダーごと置き、hugo.toml に theme = 'フォルダー名' と書くと使われます。公式のクイックスタートは、Git の submodule で入れる方法を案内しています。

git init
git submodule add https://github.com/gohugo-ananke/ananke themes/ananke
echo "theme = 'ananke'" >> hugo.toml
hugo server

テーマは公式のテーマ一覧(themes.gohugo.io)から探せます。選ぶときは、見た目より先に「テーマが求める Hugo の最低の版」を見ます。テーマの theme.toml や config/_default/module.toml に書かれています。

手元の Hugo 0.123.7 で Ananke の版を変えて試した結果

公式のクイックスタートで使われるテーマ Ananke を、版を変えて4回入れ、Ubuntu の hugo 0.123.7 でビルドしました。

Ananke の版 求める Hugo 結果
最新(2026年9月27日のコミット) 0.160.0 以上 ERROR(can't evaluate field Locale)
v2.11.0(2024年10月) 0.128.0 以上 ERROR(can't evaluate field Sass)
v2.10.0(2024年9月) theme.toml は 0.84.0、モジュール設定は 0.128.0 ERROR(can't evaluate field Sass)
v2.9.2(2024年5月) 指定なし 成功(Pages 10・233 ms)

最新の Ananke では、最初に警告が出たあと、テンプレートの実行でエラーになりました。

WARN  Module "ananke" is not compatible with this Hugo version: Min 0.160.0; run "hugo mod graph" for more information.
...
ERROR render of "home" failed: "/dev/shm/t87/mysite/themes/ananke/layouts/baseof.html:2:15": execute of template failed: template: home.html:2:15: executing "home.html" at <site>: can't evaluate field Locale in type *langs.Language
Error: error building site: render: failed to render pages: render of "404" failed: ...

「is not compatible with this Hugo version」の警告が出たら、その後のエラーを読むより先に Hugo を新しくします。テンプレートが、手元の版にまだ無い機能(ここでは Locale や css.Sass)を使っているためです。テーマのファイルが layouts/baseof.html(_default の無い場所)にあるのも、v0.146.0 以降の新しい置き場所に合わせたものです。前の版の Hugo を使い続ける事情があるなら、v2.9.2 のように当時のテーマの版を選ぶと動きましたが、テーマの修正が入らなくなるため、Hugo を上げるほうを先に考えます。

テーマの一部だけを書き換える

テーマのファイルを直接書き換えると、テーマを更新したときに消えます。サイト側の layouts/ に同じ名前のファイルを置くと、そちらが優先されます。手元で、テーマの partials/head.html をサイトの layouts/partials/head.html にコピーし、1行足してビルドすると、トップと記事の両方にその行が入りました。サイト側のファイルを消すと元に戻りました。

テーマを直したいとき

避けるthemes/ananke/layouts の中を直接書き換える。テーマの更新や submodule の取り直しで消える
→
代わりに同じ相対パスでサイトの layouts/ にコピーして直す。テーマより優先され、テーマは更新できる

見分ける問い:「テーマを入れ直しても、この変更は残るか」

最小のHugoテーマを自作する(テンプレートの基本)

この節では、外部のテーマを使わずに、ファイル7つで動く最小のテーマの中身と、テンプレートの書き方の基本が分かります。

テーマの中身は「どの種類のページを、どのテンプレートで HTML にするか」の集まりです。Hugo は、ページを home(トップ)・page(記事)・section(posts/ などの一覧)・taxonomy(タグの一覧)・term(1つのタグの記事一覧)の種類に分け、種類ごとにテンプレートを探します。手元で作った最小のテーマ mini は次の7ファイルです。

themes/mini/layouts/_default/baseof.html   全ページ共通の外枠
themes/mini/layouts/_default/home.html     トップ(記事一覧とページ分け)
themes/mini/layouts/_default/single.html   記事1本
themes/mini/layouts/_default/list.html     セクション・タグなどの一覧
themes/mini/layouts/partials/head.html     head の中身
themes/mini/layouts/shortcodes/note.html   自作のショートコード
themes/mini/static/css/style.css           CSS

外枠の baseof.html は、各ページの main の部分だけを差し替える形にします。

<!DOCTYPE html>
<html lang="{{ site.LanguageCode }}">
<head>
  {{ partial "head.html" . }}
</head>
<body>
  <header><a href="{{ "/" | relURL }}">{{ site.Title }}</a></header>
  <main>{{ block "main" . }}{{ end }}</main>
  <footer>&copy; {{ now.Year }} {{ site.Title }}</footer>
</body>
</html>

記事1本の single.html です。{{ define "main" }} で囲んだ部分が、baseof.html の block "main" に入ります。

{{ define "main" }}
<article>
  <h1>{{ .Title }}</h1>
  <time datetime="{{ .Date.Format "2006-01-02" }}">{{ .Date.Format "2006年1月2日" }}</time>
  {{ with .GetTerms "tags" }}<ul class="tags">{{ range . }}<li><a href="{{ .RelPermalink }}">#{{ .LinkTitle }}</a></li>{{ end }}</ul>{{ end }}
  {{ .Content }}
</article>
{{ end }}

トップの home.html は、posts セクションの記事をページ分けして並べます(この書き方を選んだ理由は、ビルド時間の節で数字とともに説明します)。

{{ define "main" }}
<h1>{{ site.Title }}</h1>
{{ range (.Paginate (site.GetPage "/posts").RegularPages).Pages }}
  <article>
    <h2><a href="{{ .RelPermalink }}">{{ .Title }}</a></h2>
    <time>{{ .Date.Format "2006-01-02" }}</time>
    <p>{{ .Summary }}</p>
  </article>
{{ end }}
{{ template "_internal/pagination.html" . }}
{{ end }}

ビルドすると、記事1本は次の HTML になりました(抜粋)。タグの「hugo」は、一覧では先頭が大文字の「Hugo」になっています。日本語のタグは URL では %E5%85%A5%E9%96%80 のようにエンコードされます。

<title>はじめての記事 | ミニブログ</title>
<meta name="description" content="Hugoで書いた最初の記事です。">
<link rel="stylesheet" href="/css/style.css">
...
<h1>はじめての記事</h1>
<time datetime="2026-10-29">2026年10月29日</time>
<ul class="tags"><li><a href="/tags/hugo/">#Hugo</a></li><li><a href="/tags/%E5%85%A5%E9%96%80/">#入門</a></li></ul>
<p>Hugoで最初の記事を書きました。…</p>
<aside class="note note-warn"><strong>ショートコード</strong>の中でも Markdown が使えます。</aside>

テンプレートの書き方の基本

書き方 意味 例
{{ .Title }} 今のページの値を出す .Content・.Date・.Params.xxx
{{ site.Title }} サイト全体の値 site.Params.description
{{ range … }}…{{ end }} 繰り返し 記事・タグを並べる
{{ with … }}…{{ end }} 値があるときだけ タグが無い記事では何も出さない
{{ "css/style.css" | relURL }} 関数に値を渡す(パイプ) サブフォルダーで公開しても崩れない
{{ partial "head.html" . }} 部品を読み込む 最後の . で今のページを渡す

日付の書式は Go の決まりで、2006-01-02 15:04 という「決まった日時」を見本として書きます。YYYY-MM-DD のようには書きません。

v0.146.0 からの新しい置き場所

公式ドキュメントによると、Hugo v0.146.0 でテンプレートの扱いが作り直され、置き場所が変わりました。以前の構成も対応表で読めるようにしてある、と書かれていますが、不具合の報告もあるとされています。新しく作るテーマは新しい置き場所に合わせます。

以前(0.123.7 で使用) v0.146.0 以降
layouts/_default/baseof.html など layouts/baseof.html(_default は廃止)
layouts/partials/ layouts/_partials/
layouts/shortcodes/ layouts/_shortcodes/
layouts/index.html(トップ) layouts/home.html
taxonomy.html を term にも使う taxonomy.html と term.html を分ける

コマンドで作るなら hugo new theme 名前 で、ヘッダー・メニュー・CSS・サンプル記事まで入ったひな形(手元の 0.123.7 では25ファイル)ができます。中身を読みながら削っていくと、テンプレートの仕組みを覚えやすくなります。

タクソノミー・ショートコード・画像処理の使い方

この節では、タグやカテゴリーの一覧ページ、記事の中で使う部品(ショートコード)、画像の縮小の3つが、実際の出力とともに分かります。

タクソノミー(タグ・カテゴリー)

フロントマターに tags と categories を書くだけで、Hugo は一覧ページと RSS を自動で作ります。設定で何も書かなくても tags と categories は使えます。手元の hugo.toml では明示しました。

[taxonomies]
  tag = 'tags'
  category = 'categories'

記事2本(タグ3種・カテゴリー2種)でビルドすると、次のファイルができました。

public/tags/index.html
public/tags/hugo/index.html
public/tags/hugo/index.xml
public/tags/テンプレート/index.html
public/tags/入門/index.html
public/categories/index.html
public/categories/お知らせ/index.html
public/categories/技術/index.html

ショートコード(記事の中で使う部品)

ショートコードは、Markdown に書けない部品を {{< 名前 >}} の形で呼び出す仕組みです。公式ドキュメントに載っている組み込みのショートコードは details・figure・highlight・instagram・param・qr・ref・relref・vimeo・x・youtube の11種類です。手元では組み込みの ref と highlight、自作の note を使いました。

<aside class="note note-{{ .Get "type" | default "info" }}">{{ .Inner | markdownify }}</aside>

これを layouts/shortcodes/note.html に置くと、記事の中で {{< note type="warn" >}}…{{< /note >}} と書けます。ref は記事のファイル名から URL を作るので、URL を変えてもリンクが切れません。手元では {{< ref "second.md" >}} が https://example.com/posts/second/ になりました。

書き方 処理の順番(公式) 使う場面
{{< 名前 >}} 別に処理して、Markdown の変換後に合わせる HTML を出す部品
{{% 名前 %}} Markdown の変換の前に処理する 中に見出しを書き、目次に載せたい

Markdown の中に HTML を直接書くと、既定では出力されません。手元で <span style="color:red"> を書いた記事をビルドすると、その部分が「raw HTML omitted」という HTML コメントに置き換わりました。HTML をそのまま出すには設定の [markup.goldmark.renderer] unsafe = true が要りますが、記事を書く人が多いサイトでは、ショートコードで必要な部品だけを用意するほうが安全です。

画像の縮小(ページバンドル)

記事を「フォルダー+index.md」の形(ページバンドル)にすると、同じフォルダーの画像をテンプレートから加工できます。800×400 の PNG(100,757 バイト)を置き、次のショートコードで幅400の WebP にしました。

{{ with .Page.Resources.Get (.Get 0) }}
  {{ $img := .Resize "400x webp q75" }}
  <img src="{{ $img.RelPermalink }}" width="{{ $img.Width }}" height="{{ $img.Height }}" alt="">
{{ end }}
100,757B元の PNG800×400
1,132B書き出された WebP400×200・q75
56ms変換を含むビルドProcessed images 1

加工した画像は resources/_gen/ にも保存され、2回目からは変換し直さずに使われます。このフォルダーは Git に入れておくと CI のビルドが速くなり、入れなければ毎回変換します。

hugoでビルドして公開する(publicの中身とデプロイ先)

この節では、公開用のファイルを書き出すコマンドと、できるファイル、サブフォルダーで公開するときの注意、置き場所の選び方が分かります。

公開用のファイルは、オプションを付けずに hugo と打つと public/ に書き出されます。最新のドキュメントでは hugo build とも書かれていますが、手元の 0.123.7 では次のエラーになりました。以前の版では hugo だけで書き出します。

$ hugo build
Error: command error: unknown command "build" for "hugo"

記事3本(1本は画像つき)のサイトをビルドした結果です。

$ hugo
Start building sites …
hugo v0.123.7+extended linux/amd64 BuildDate=2025-07-18T03:41:49Z VendorInfo=ubuntu:0.123.7-1ubuntu0.3

                   | EN
-------------------+-----
  Pages            | 24
  Paginator pages  |  0
  Non-page files   |  0
  Static files     |  1
  Processed images |  1
  Aliases          |  1
  Cleaned          |  0

Total in 24 ms

表の「EN」は、languageCode = 'ja' にしても変わりませんでした。これは表示用の言語の区分(defaultContentLanguage の既定値 en)で、hugo config で見ると defaultcontentlanguage = 'en' のままでした。HTML の lang="ja" は languageCode から出ています。

オプション 働き 手元の結果
なし public/ に書き出す 28ファイル。HTML 計10,940バイト
--minify HTML・XML などの空白を詰める HTML 計10,093バイト(約8%減)
--gc 使われなくなったキャッシュを消す resources/_gen の掃除
--cleanDestinationDir 出力先の不要なファイルを消す 消した記事の HTML が残らない
-d フォルダー 出力先を変える public/ 以外に書き出す
--baseURL 公開先の URL を上書きする CI でプレビュー用の URL にする

記事を消しても、public/ にある以前の HTML は自動では消えません。公開の前に public/ を消してからビルドするか、--cleanDestinationDir を付けます。

サブフォルダーで公開するとき(baseURL と relURL)

GitHub Pages のプロジェクトサイトのように https://example.com/blog/ の下で公開するときは、baseURL にフォルダーまで書きます。手元で baseURL を https://example.com/blog/ にすると、テンプレートで relURL を通した CSS とタグのリンクは /blog/css/style.css・/blog/tags/hugo/ になりました。テンプレートに /css/style.css と直接書いた場合は /css/style.css のまま出力され、公開先では CSS が読み込めない形になりました。

サイトマップと予約投稿の記事

sitemap.xml には公開した13の URL が入り、日付が未来の記事は入りませんでした。ただし、手元の 0.123.7 では、トップと posts/ の lastmod が未来の記事の日付(2026-12-01)になっていました。予約投稿を置いたまま公開する場合は、公開前に sitemap.xml の lastmod も見ておきます。

デプロイ先

public/ はただのファイルの集まりなので、静的ファイルを置ける場所ならどこでも公開できます。公式ドキュメントの「Host and deploy」には、AWS Amplify・Azure Static Web Apps・Cloudflare・Codeberg Pages・Firebase・GitHub Pages・GitLab Pages・Netlify・Render・Vercel と、FTP・Rclone・Rsync・Hugo CLI(hugo deploy)での手順が載っています。

Hugoのビルド時間を実測(記事1,000本・5,000本・1万本)

この節では、記事の数を増やしたときに Hugo のビルド時間がどう伸びるかと、テンプレートの書き方1つで時間が半分になった例が分かります。

記事を Python で自動生成し、自作のテーマ mini で5回ずつビルドしました。記事は1本あたり約8KB(見出し・本文5段落・Go のコードブロック1つ・タグ3つ、タグは全部で50種類)です。手元は2 vCPU でほかの処理と同居しているため、数値には振れがあります。表は5回の中央値です。

記事数 Pages 書き換え前の home.html 書き換え後の home.html 出力
1,000本 1,109 0.90秒 0.77秒 1,310ファイル・11MB
5,000本 5,109 9.8秒 5.7秒 6,110ファイル・54MB
1万本 10,109 32.9秒 15.8秒 12,110ファイル・107MB

書き換え前は、記事が5倍・10倍になると、時間が11倍・37倍に伸びていました。--templateMetrics で、どのテンプレートに時間がかかっているかを見ると、トップの home.html が飛び抜けていました(5,000本のとき)。

$ hugo --templateMetrics
     cumulative       average       maximum
       duration      duration      duration  count  template
     ----------      --------      --------  -----  --------
  10.712942233s   10.712942ms  102.679666ms   1000  _default/home.html
   8.147165199s    1.629433ms   62.316252ms   5000  _default/single.html
   790.128661ms   14.632012ms  232.919646ms     54  _internal/_default/rss.xml

トップは5本ずつのページ分けで1,000ページあり、その1ページごとに where site.RegularPages "Section" "posts" が全記事を調べ直していました。記事数×ページ数で増えるため、記事が増えるほど急に遅くなります。

トップで posts の記事を並べるとき

遅い.Paginate (where site.RegularPages "Section" "posts")。ページごとに全記事を絞り込み直す。home.html の合計 10.7秒
→
速い.Paginate (site.GetPage "/posts").RegularPages。セクションが持つ一覧をそのまま使う。合計 2.6秒

見分ける問い:「ページ分けの1ページごとに、全記事を調べていないか」

0.77秒記事1,000本2 vCPU・書き換え後
15.8秒記事1万本書き換え前は 32.9秒
52%減1行の書き換え1万本のとき

参考に、本文が1行だけの記事1,000本では0.52〜1.08秒でした。本文の長さとコードの色付けも時間に効きますが、それ以上に「1ページごとに全記事を回す処理」がテンプレートのどこかにあるかで、記事が増えたときの時間が大きく変わります。外部のテーマを使っていて遅いと感じたら、まず --templateMetrics で上位のテンプレートを見ます。--templateMetricsHints を足すと、partialCached に置き換えられそうな部品の候補も表示されます。

Hugoのよくあるエラーと直し方(原文つき)

この節では、Hugo を使い始めたときによく出るエラーの原文と、原因と直し方が一覧で分かります。

Hugo のエラーは「ファイルのパス:行:列」が付いているので、まずその場所を開きます。手元の 0.123.7 でわざと起こしたエラーです。

エラーの原文(抜粋) 原因 直し方
Unable to locate config file or config directory. Perhaps you need to create a new site. サイトのフォルダーの外で実行した hugo.toml のあるフォルダーへ cd する
module "nothere" not found in ".../themes/nothere"; either add it as a Hugo Module or store it in ".../themes". theme の名前と themes/ のフォルダー名が違う・submodule が空 名前を合わせる。git submodule update --init
Module "ananke" is not compatible with this Hugo version: Min 0.160.0 テーマが求める版より Hugo の版が低い Hugo を上げる
found no layout file for "html" for kind "home" テーマが無い・テンプレートが足りない テーマを入れる。該当の種類のテンプレートを作る
parse failed: template: _default/single.html:9: unexpected EOF {{ end }} が足りない range・with・if・define の数と end の数を合わせる
can't evaluate field Contnet in type *hugolib.pageState ページの値の名前の打ち間違い .Content のように正しい名前にする
failed to unmarshal YAML: yaml: line 2: did not find expected key YAML のフロントマターの書き方の誤り(引用符の閉じ忘れ) 値を "…" で正しく囲む
unmarshal failed: toml: incomplete number TOML で文字列を引用符で囲んでいない title = '…' と囲む
failed to extract shortcode: template for shortcode "youtube2" not found 無いショートコードを呼んだ 名前を確かめる。layouts/shortcodes/ に作る
shortcode "note" must be closed or self-closed 閉じタグ {{< /note >}} が無い 閉じタグを書く
REF_NOT_FOUND: Ref "nothere.md": … page not found ref で指定した記事が無い・下書き ファイル名を確かめる
unknown command "build" for "hugo" Hugo の版が低い(build は新しい版の書き方) hugo だけで書き出す
server startup failed: listen tcp 127.0.0.1:48787: bind: address already in use 指定したポートを別のプロセスが使っている 別の --port を指定するか、前のサーバーを止める

エラーにならないつまずきもあります。

  • 記事が出ない:draft = true、日付が未来、expiryDate を過ぎた、のどれか。hugo list drafts・hugo list future で確かめます。
  • Markdown に書いた HTML が消える:既定では「raw HTML omitted」に置き換わります。前の節のとおりです。
  • CSS が当たらない(公開先だけ):baseURL とテンプレートのパスの書き方。relURL・absURL を通します。
  • 保存しても画面が変わらない:--disableFastRender を付けて起動し直します。
  • 1hugo version と CI の版が同じかテーマの最低の版も満たしているか
  • 2baseURL が公開先の URL かサブフォルダーで公開するならフォルダーまで書く
  • 3-D を付けずにビルドしたか下書きを公開しない
  • 4public/ を消してからビルドしたか消した記事の HTML を残さない
  • 5WARN の行が出ていないかテンプレートが無い種類のページは HTML ができない

Astro・Next.js・WordPressとの違い(どれを選ぶか判断表)

この節では、Hugo と、よく比べられるサイト作りの道具の違いと、どんなときに Hugo を選ぶかが分かります。

Hugo は「Markdown の記事が多いサイトを、JavaScript の環境なしで速く書き出す」ことに向いています。画面の動きが多いサイトや、React の部品を使いたい場合は、Astro や Next.js が候補になります。

Hugo Astro Next.js WordPress
書く言語 Markdown+Go テンプレート Markdown・.astro・React など React(JSX・TSX) 管理画面+PHP テーマ
動かすのに要るもの hugo の実行ファイルだけ Node.js と npm Node.js と npm PHP と MySQL のサーバー
出力 静的ファイルだけ 静的が基本、サーバー処理も可 静的・サーバー処理の両方 アクセスのたびに生成
記事を書く人 Git とファイルを扱える人 同左 同左(CMS と組み合わせることが多い) 管理画面を使える人
向くサイト 記事・ドキュメントが多いサイト 記事中心で一部に動きのあるサイト ログインなど機能の多い Web アプリ 書く人が多い・更新が多いサイト
  1. 1管理画面から書く人が多い → WordPress やヘッドレス CMSGit を使わない人が記事を書く
  2. 2ログイン・決済などサーバー側の処理が中心 → Next.js静的サイトの範囲を超える
  3. 3記事中心だが React の部品を一部で使いたい → Astro必要な部品だけ JavaScript を送れる
  4. 4Markdown の記事・ドキュメントが中心で、Node.js を入れたくない → Hugo数千本でもビルドが短い

Next.js の App Router の作り方とビルドの出力は、関連記事「Next.js App Router 入門|v16対応・実際のビルド結果つき」で扱っています。Hugo の記事で使う Markdown の記法は関連記事「Markdownの書き方一覧|記法早見表と環境別の対応・変換結果つき」で、hugo.toml の TOML と YAML の違いは関連記事「CSV・JSON・XML・YAML・TOMLの違いと使い分け|同じデータで比較」で扱っています。

よくある質問

Q. Hugo とは何ですか? A. Go 言語で作られた静的サイトジェネレーターです。Markdown の記事とテンプレートから、HTML・CSS・RSS・サイトマップを public/ フォルダーに書き出します。書き出したファイルを置くだけで公開できます。

Q. Hugo は無料ですか? A. オープンソース(Apache License 2.0)で、無料で使えます。費用がかかるとすれば、公開に使うホスティングとドメインです。

Q. Go 言語を知らなくても使えますか? A. 使えます。Go 言語のプログラムを書くことはありません。テンプレートは Go の text/template の書き方({{ .Title }} など)を使いますが、テーマを使うだけならテンプレートを書かずに始められます。

Q. standard 版と extended 版のどちらを入れればよいですか? A. 公式は「追加の機能が要らなければ standard」と案内しています。テーマが SCSS を使っていて README に extended が必要と書かれていれば extended を選びます。Mac の brew、Windows の winget で入るのは extended です。

Q. テーマを入れたらエラーになりました。 A. 最初に「is not compatible with this Hugo version: Min …」の警告が出ていないかを見ます。出ていれば Hugo の版が足りないことが原因です。手元では、Ubuntu の apt で入る 0.123.7 に最新の Ananke を入れると「can't evaluate field Locale」で止まりました。

Q. 書いた記事が表示されません。 A. フロントマターの draft が true か、date・publishDate が未来の日時になっていることが多いです。hugo list drafts と hugo list future で確かめ、確認だけなら hugo server -D -F で表示できます。

Q. hugo server で作ったページをそのまま公開できますか? A. 公開には使いません。hugo server は確認用で、ライブリロードのスクリプトが差し込まれます。hugo で書き出した public/ を Web サーバーやホスティングに置きます。

Q. 記事が何本くらいまで実用的にビルドできますか? A. 手元の2 vCPU では、1万本で約16秒でした。ただし、テンプレートの書き方次第で倍以上かかることがあり、同じ1万本で書き換え前は約33秒でした。遅いときは --templateMetrics で原因のテンプレートを探します。

Q. WordPress から Hugo へ移せますか? A. 記事を Markdown に書き出せば移せます。ただしコメント・問い合わせフォーム・会員機能など、サーバー側で動いていた機能は、外部のサービスで置き換える必要があります。URL を変えるなら、フロントマターの aliases で以前の URL からの転送ページを作れます。

Q. config.toml と hugo.toml の違いは? A. どちらも設定ファイルです。新しい版の hugo new site は hugo.toml を作ります。手元の 0.123.7 の help には「config file (default is hugo.yaml|json|toml)」と表示されました。

まとめ

  • Hugo は Go 製の静的サイトジェネレーター。hugo new site→hugo new content→hugo server→hugo の4段で使え、public/ を置くだけで公開できる。
  • OS のパッケージは最新の版とは限らない。手元の Ubuntu 24.04 の apt は 0.123.7 で、2026年10月29日時点の最新 v0.169.0 とはマイナー版で46の差があった。
  • テーマのエラーは、まず版を疑う。最新の Ananke は Hugo 0.160.0 以上を求め、0.123.7 では「can't evaluate field Locale」で止まった。v0.146.0 以降はテンプレートの置き場所も変わっている。
  • テーマは直接書き換えず、サイトの layouts/ に同じパスで置いて上書きする。最小のテーマはファイル7つで作れた。
  • 記事1万本のビルドは約16秒。トップのページ分けで where site.RegularPages を使うと約33秒かかり、site.GetPage "/posts" に変えるだけで半分になった。

参考・出典

確認日はいずれも 2026年10月29日です。

  • Hugo「Quick start」:https://gohugo.io/getting-started/quick-start/
  • Hugo「Linux」(インストール):https://gohugo.io/installation/linux/
  • Hugo「macOS」(インストール):https://gohugo.io/installation/macos/
  • Hugo「Windows」(インストール):https://gohugo.io/installation/windows/
  • Hugo「hugo server」:https://gohugo.io/commands/hugo_server/
  • Hugo「hugo build」:https://gohugo.io/commands/hugo_build/
  • Hugo「hugo new project」:https://gohugo.io/commands/hugo_new_project/
  • Hugo「Front matter」:https://gohugo.io/content-management/front-matter/
  • Hugo「Shortcodes」:https://gohugo.io/content-management/shortcodes/
  • Hugo「New template system overview」:https://gohugo.io/templates/new-templatesystem-overview/
  • Hugo「Configure pagination」:https://gohugo.io/configuration/pagination/
  • Hugo「Host and deploy」:https://gohugo.io/host-and-deploy/
  • Hugo Themes:https://themes.gohugo.io/
  • GitHub「gohugoio/hugo Releases」(v0.169.0):https://github.com/gohugoio/hugo/releases
  • GitHub「theNewDynamic/gohugo-theme-ananke」:https://github.com/theNewDynamic/gohugo-theme-ananke
  • Ubuntu 24.04 のリポジトリ(noble-updates/universe・noble-security/universe)の hugo 0.123.7-1ubuntu0.3:apt-cache policy hugo で確認

Hugo の実行ファイルは Go 言語で作られています。Go そのものの文法は関連記事「Go言語入門|1.27対応の基本文法を実行結果つきで解説」で扱っています。

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「Hugoとは・使い方|テーマ自作と1万記事のビルド実測・エラー原文」

株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。

WE ARE HIRING

RJCで一緒に開発しながら、
成長を楽しみませんか?

RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!

  • 127日年間休日
  • 12時間平均残業時間
  • 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!

ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。

ABOUT RJC RJCがどんな会社か知る 考え方、研修、働き方、福利厚生、社員の前職まで。RJCのことが丸わかり! RJC丸わかりページへ JOB DESCRIPTION 仕事内容・待遇を見てみる 仕事内容、給与・待遇、選考の流れ。経験者も未経験も!応募前に知りたいこと、まとめました! 募集要項を見る ENTRY エントリーする エントリーは1〜2分・履歴書不要です。まずは話を聞いてみたい、という方でも歓迎です! エントリーフォームへ
参加受付中

AI駆動開発、 無料セミナー