Hugo 使用ガイド

対象バージョン:Hugo v0.168.0(Extended)。コマンドは macOS/Linux のシェル例を記載。Hugo 公式ドキュメントに基づき整理。テーマ固有の非公開設定は実際のテーマリポジトリに従ってください。

1. インストールとバージョン確認

macOS(Homebrew):

brew install hugo
hugo version
hugo env

Linux では、対応するディストリビューションのパッケージ、または Hugo 公式がリリースするバイナリを利用できます。SCSS/Sass や一部テーマのアセットパイプラインを使う場合は、インストールしたバージョンに Extended 機能が含まれているか確認してください。

2. プロジェクトの作成

hugo new project myblog
cd myblog
git init

典型的なディレクトリ構成:

myblog/
├── archetypes/       # 新規記事のテンプレート
├── assets/           # リソースパイプラインで処理するアセット
├── content/          # Markdown コンテンツ
├── data/             # データファイル
├── i18n/             # テーマ UI の翻訳
├── layouts/          # カスタムテンプレート(テーマを上書き可)
├── static/           # サイトのルートへそのままコピーされる
├── themes/           # ローカルテーマ/Git サブモジュール
├── hugo.toml         # サイト設定(YAML など他形式も可)
└── public/           # ビルド成果物(hugo 実行後に生成)

Hugo 本体にはブログ用の完成した外観テーマは付属しません。利用可能なテーマや独自レイアウトがない場合、found no layout file for "html" のような警告が出ることがあります。

3. 既存テーマを利用する(Git サブモジュール)

以下では、Hugo 公式クイックスタートで採用されている Ananke テーマを例に説明します。

git submodule add https://github.com/gohugo-ananke/ananke themes/ananke

hugo.toml で設定します(同じ TOML キーを重複宣言しないでください)。

baseURL = 'https://example.com/'
title = 'My Blog'
theme = 'ananke'

プレビューを起動:

hugo server -D

テーマによってメニュー、ホームページ、パラメータ、Hugo バージョン、アセットのビルド依存関係は異なります。設定を移行する際は、テーマの README とサンプルサイトを優先して参照してください。他テーマの [params] をそのまま流用しないでください。

Git サブモジュールの運用

新しいマシンでクローン:

git clone --recurse-submodules <リポジトリ URL>

既存クローンでサブモジュールを補完:

git submodule sync --recursive
git submodule update --init --recursive

サブモジュールの更新(設定されたリモートブランチを追跡します。変更を確認してからコミットしてください):

git submodule update --remote --merge
git diff --submodule
git add .gitmodules themes/
git commit -m 'Update Hugo theme'

サブモジュールの Git URL を移行する場合は、まず .gitmodules の url を修正し、その後 git submodule sync --recursive を実行します。CI のネットワークが不安定な場合は、アクセス可能な Git ミラーへ切り替えることもできますが、ミラーが必要なコミットオブジェクトを保持していることを確認してください。あるいは、メインリポジトリをクローンした後でサブモジュールを自前で初期化する方法もあります。

4. 記事の作成と編集

hugo new content posts/hello-world.md

記事の例:

---
title: "Hello World"
date: 2026-10-17T12:00:00+08:00
draft: false
description: "記事の概要"
tags: ["Hugo", "ブログ"]
categories: ["技術"]
---

本文です。

## 第一節

**太字**、*斜体*、[外部リンク](https://gohugo.io)。

主要フィールド:

フィールド用途
titleタイトル
date記事の日時
drafttrue で下書き。デフォルトの本番ビルドでは公開されない
description概要。表示するかはテーマ次第
tags, categories分類。詳細ページの表示はテーマ次第
slugURL 末尾をカスタマイズ(実際のパスは permalink 設定にも影響される)

注意:未来日時の記事もデフォルトでは本番ビルドに含まれないことがあります。日付、タイムゾーン、--buildFuture を確認してください。

画像と静的ファイル

サイト全体の静的ファイルは static/images/logo.png に置き、記事から次のように参照します。

![Logo](/images/logo.png)

ページバンドルを使う場合は以下の構成が可能です。

content/posts/hello/
├── index.md
└── cover.jpg

index.md 内に ![Cover](cover.jpg) と記述します。テーマの画像処理やサムネイル機能を使う場合は、そのテーマのページリソース規約に従う必要があります。

5. ローカル開発とビルド

hugo server                  # 公開済み内容をプレビュー
hugo server -D               # 下書きも対象
hugo server --bind 0.0.0.0   # 他デバイスからの接続を許可。ネットワークアクセス制御に注意
hugo                         # public/ へ出力
hugo --gc --minify           # 一般的な本番ビルド
hugo -d dist                 # dist/ へ出力

Hugo のビルドコマンドは、ビルド前に出力ディレクトリを自動で消去しません。記事の削除、URL 変更、言語切替を行うと、古いファイルが残ることがあります。任意のパスを確認なしに削除するのではなく、CI の一時ビルドディレクトリ内で生成物をクリアしてからビルドすることを推奨します。

rm -rf public
hugo --gc --minify

public/ が純粋なビルド成果物であり、ユーザーデータを含まないことが確認できた場合に限り、上記の削除を実行してください。

6. 多言語サイト

以下は中国語と英語の基本設定例です。対応する言語メニューや切替方式はテーマによって異なります。

baseURL = 'https://example.com/'
title = 'My Blog'
defaultContentLanguage = 'zh-cn'
defaultContentLanguageInSubdir = false

[languages]
  [languages.zh-cn]
    languageName = 'Simplified Chinese'
    languageCode = 'zh-CN'
    weight = 1
    title = '我的博客'
  [languages.en]
    languageName = 'English'
    languageCode = 'en-US'
    weight = 2
    title = 'My Blog'

言語ディレクトリでコンテンツを整理する一例:

content/
├── zh-cn/
│   └── posts/hello.md
└── en/
    └── posts/hello.md

上記の言語ディレクトリ構成を使う前に、多言語コンテンツディレクトリ設定または言語マウントと組み合わせて、コンテンツが正しく所属するか確認してください。追加マウントが不要でより簡単な方法は、同じディレクトリ内で翻訳ファイル名(hello.zh-cn.md と hello.en.md など)を使うことです。デフォルト言語の URL もプロジェクト設定に応じて配置できます。

推奨:すでに content/posts/ が存在するサイトでは、まずファイル名サフィックス方式を採用してください。

content/posts/
├── hello.zh-cn.md
└── hello.en.md

翻訳ページには一貫した translationKey を設定するとよいでしょう(ファイルパスで直接関連付けられない場合のみ必要)。多言語メニューが誤ったページを指すのを防ぎます。

7. Markdown 内で HTML を使う

Hugo はデフォルトで Goldmark を使用します。ログに Raw HTML omitted while rendering と表示される場合、Markdown 内の生の HTML は描画されていません。記事内容を信頼できる場合にのみ、hugo.toml で以下を有効化してください。

[markup.goldmark.renderer]
  unsafe = true

有効化すると、記事内の埋め込み HTML が出力に含まれるようになります。内容が信頼できない投稿源から来る場合は、スクリプトインジェクションのリスクを考慮してください。

8. Git と Gitea Actions による公開

ソースリポジトリ(.gitmodules、content/、hugo.toml 等を含む)と静的公開リポジトリ/ブランチは分離することを推奨します。CI の典型的なフロー:

push to source main
       │
       ▼
ソースとテーマサブモジュールを取得
       │
       ▼
指定バージョンの Hugo をインストール
       │
       ▼
一時ビルド出力をクリアし hugo --gc --minify を実行
       │
       ▼
public/ のファイルを公開リポジトリの main/公開ブランチへコミット
       │
       ▼
Caddy / Nginx が静的ディレクトリを提供

ビルドコンテナ内で以下のコマンドをまず検証できます。

git submodule sync --recursive
git submodule update --init --recursive
rm -rf public
hugo --gc --minify
find public -maxdepth 2 -type f | head

Gitea Actions のサンプルワークフローは、act_runner のラベル、コンテナイメージ、Git 認証、権限、Hugo のインストールパス、対象ブランチに応じて個別に設定する必要があります。GITHUB_SHA や独自の COMMIT_SHA がすべてのシェルステップに自動で存在するとは限りません。set -u を用いるスクリプトでは、未定義変数がビルドを直接失敗させます。ソースコミットの値を取得するには、チェックアウト済みの Git リポジトリ内で以下を実行してください。

SOURCE_SHA="$(git rev-parse HEAD)"

公開対象リポジトリには別の作業ディレクトリを使用し、ソースファイルの誤削除を防ぎます。プッシュ前にブランチの non-fast-forward 衝突を確認してください。チェックなしの git push --force を一般的な公開戦略としないことを推奨します。

9. よくあるトラブルシューティング

9.1 found no layout file for "html"

原因は通常、テーマが正しく読み込まれていない、対応テンプレートがテーマに存在しない、または設定ファイルの theme 名が themes/ ディレクトリと一致しないことです。

ls -la themes/
cat .gitmodules
hugo config | grep -i theme
hugo --logLevel debug

テーマディレクトリ内に layouts/ などのテンプレートファイルが実際に存在するか確認し、テーマ自身の利用ガイドも確認してください。空サイトの警告を無視して解決としないでください。

9.2 Raw HTML omitted

第 7 節に従い markup.goldmark.renderer.unsafe を確認してください。生の HTML を Markdown や Hugo ショートコードに置き換えることも検討してください。

9.3 Git サブモジュールディレクトリが空

git submodule status --recursive
git submodule update --init --recursive

ネットワークエラーが報告された場合は、ホスト側だけでなく .gitmodules の URL、認証情報、ビルドコンテナ内の DNS/プロキシを確認してください。

9.4 ページが公開されない

記事の draft、日付、公開期限、言語、対象テーマのルーティングを確認してください。以下を実行して確認できます。

hugo list all
hugo list drafts
hugo list future
hugo list published

9.5 CI ビルドは成功したが公開内容が変わらない

public/ に期待する HTML が含まれているか、公開ブランチが更新されたか、Web ルートが最新のデプロイ先を指しているか、ブラウザ/CDN が古いコンテンツをキャッシュしていないかを確認してください。最初に Hugo のキャッシュ問題と決めつけないでください。

10. 推奨される日常ワークフロー

# 1. 更新を取得(サブモジュール含む)
git pull --ff-only
git submodule update --init --recursive

# 2. 新規記事を作成
hugo new content posts/new-post.md

# 3. 編集してローカルでプレビュー
hugo server -D

# 4. 記事の front matter で draft を false に変更

# 5. コミットしてプッシュ(CI が自動でビルド/公開)
git add content/
git commit -m 'Add new post'
git push

11. 参考資料