Hugo ことはじめ
この記事は,Hugo について全体を簡単にまとめたものです。
インストールについては こちら を参照してください。様々な方がコンテナイメージを作成していますので,それを参考にしても良いと思います。また,devcontainer 向けとして Hugo がモジュールとして提供されています。
🦜プロジェクトの作成 [1]
はじめにサイト(プロジェクト)を作成します。
新しいプロジェクトを作成するには,以下のコマンドを使用します。
hugo new site <Project名>
このコマンドを実行すると,指定した <Project名> のディレクトリが作成され,その中に Hugo プロジェクトのひな形が展開されます。
📁ディレクトリ構造 [2]
新規プロジェクト作成後のディレクトリ構成は以下のとおりです。
Project名/
├── archetypes/
│ └── default.md
├── assets/
├── content/
├── data/
├── i18n/
├── layouts/
├── static/
├── themes/
└── hugo.toml
以下,各ディレクトリ(一部ファイル含む)の説明です。
| ディレクトリ | 説明 |
|---|---|
| archetypes |
hugo newで新規ページを作成する時のテンプレートを格納 |
| assets | パイプラインを通じて変換するSASSやJavaScriptなどを格納 |
| content | 記事やページなどのコンテンツをMarkdownファイルとしてここに配置 |
| data | サイト内で使う追加データ(YAML, JSON, TOML)を格納 |
| i18n | 多言語対応の翻訳ファイル |
| layouts | レイアウトのテンプレートを格納 |
| static | 画像やCSSなど,そのまま出力される静的ファイルを格納 |
| themes | 使用するテーマを配置 |
| hugo.toml | プロジェクトの設定ファイル。config/_default/hugo.toml などと分割することも可能で,テーマによっては配置場所が異なる場合がある |
hugoまたはhugo serverコマンドを実行することでサイト本体をビルドすることができ,この際に以下のディレクトリが追加されます。
| ディレクトリ | 説明 |
|---|---|
| public | ビルドされた静的サイトの出力先。デプロイ時にはこのフォルダの内容をサーバにアップロードする |
| resource | パイプライン処理後のリソースキャッシュ用ディレクトリ。ビルド後のCSSや圧縮された画像が入る |
⚙️設定ファイル[3][4]
Hugo の設定ファイルは初期ではhugo.tomlが用意されていますが,TOML,YAML,JSON形式で記述ができます。複数ファイルがある場合はhugo.toml → hugo.yaml → hugo.json の順で読み込まれます。
以下は設定項目例です。有効な識別子とするため,キー名はキャメルケースまたはスネークケースを使用する必要があります。
baseURL = 'https://localhost:1313/' # baseとなるURL
languageCode = 'en-us' # 言語コード
title = 'My New Hugo Site' # サイトのタイトル
[params] # カスタムパラメータ
customCSS = ["./custom.css"]
favicon = "./img/favicon.ico"
theme = "book"
enableGitInfo = true
1つの設定ファイルではなく,環境ごとや言語ごとに設定ファイルを分割することもできます。
my-project/
└─ config/
├─ _default/
│ ├─ hugo.toml
│ ├─ menus.toml
│ └─ params.toml
├─ production/
│ ├─ hugo.toml
│ ├─ params.toml
└─ development/
├─ hugo.toml
└─ params.toml
_default配下は文字通りデフォルトで読み込まれます。
production,developmentなどの環境ごとフォルダを作成し,次のコマンドのように--environmentで指定することで,_default設定に上書きし,各環境ごとの設定をすることができます。
hugo server --environment development
また--configを使うことで,ビルド時に特定のファイルを優先して読み込んだり,複数ファイルをマージすることも可能です。
hugo --config custom.toml
hugo --config hugo.toml,production/params.toml
環境変数によって設定を上書きすることもできます。環境変数は設定ファイルより優先されるため,CI/CD環境やコンテナ運用で有用です。
-
HUGO_BASEURL:baseURL -
HUGO_ENABLEGITINFO:enableGitInfo -
HUGO_ENVIRONMENT:ビルド時の環境(production/development)
また,以下のコマンドにより,完全な設定構成を表示させることができます。
hugo config
📚コンテンツページ
コンテンツ自体はcontentディレクトリ配下にMarkdown記法で作成していきます。
ページを追加する
手動で Markdown ファイルを作成してもいいですが,CLIを使うとテンプレート付きのページを効率よく追加できます。
hugo new content content/post/test-page.md
このコマンドを実行すると,architypes/配下にあるテンプレートに基づいてページが生成されます。途中のディレクトリも自動で作成されるため,事前のフォルダ準備は不要です。
+++
date = '{{ .Date }}'
draft = true
title = '{{ replace .File.ContentBaseName "-" " " | title }}'
+++
+++
date = '2025-05-31T07:00:11Z'
draft = true
title = 'Test Page'
+++
レイアウトテンプレート
レイアウトのテンプレートは,文字通りlayoutsディレクトリ配下にHTMLテンプレートとして配置します。
Hugoはレイアウトのテンプレートがないとレンダリングできません。テンプレートが用意されていない場合,ビルドしても「Page Not Found」と表示されてしまいます。そのため,とりあえず表示させたい場合,以下のような簡単なテンプレートをlayouts/all.htmlに置くだけでも動作します。
<h1>{{ .Title }}</h1>
{{ .Content }}
このテンプレートを使ってページをビルドすると,次のようにタイトルと本文だけが表示されます。

Theme
上記のレイアウトテンプレートを一から書くのが面倒,あるいはサイトの見た目を一気に整えたいという場合は,テーマを使うのが最も手っ取り早いです。
Theme一覧ページ から好みのものを選ぶことができます。適用方法は各ThemeのREADMEにあるかと思います。
デザインだけでなく事前に用意されている機能などにも違いがあるので,機能や作りたいページのイメージに合わせて選択します。
テンプレート構成例
各Themeのlayoutsディレクトリの中にもあると思いますが,トップページやページの一覧を表示するページ,末端のページなどでそれぞれ layout ファイルを作成することができます,構成はテーマによって異なりますが,以下は「book」テーマの一部を参考にしています。
layouts/
├─ post/ # セクションまたはタイプが「post」の際に使用
│ ├─ single.html
│ └─ list.html
├─ _shortcodes/ # Markdownファイル内で呼び出せる部品(ショートコード)
│ ├─ button.html
│ ├─ hint.html
│ └─ tab.html
├─ _partials/ # ヘッダー・フッター・メニューバーなどの再利用する部品
│ ├─ footer.html
│ ├─ header.html
│ ├─ menu.html
│ ├─ search.html
│ └─ toc.html
├─ baseof.html
├─ single.html
├─ list.html
├─ home.html
├─ 404.html
├─ term.html
├─ taxonomy.html
└─ all.html
様々なテンプレートファイルがありますが,簡単にまとめると以下のようなものがあります。
| ファイル | 説明 |
|---|---|
| baseof.html | サイト共通,文字通りbaseとなる部分 |
| home.html | トップページのレイアウト |
| single.html/page.html | 通常のコンテンツページをレンダリング。page.htmlが存在しないとsingle.htmlにフォールバックされる |
| section.html | セクション(/posts/など)配下のページ一覧をレンダリング。 |
| term.html | 各タグのページをデザイン。 |
| taxonomy.html | タグやカテゴリの一覧ページ |
| list.html |
home/section/taxonomy/termテンプレートが存在しない場合にフォールバック |
| all.html | 上記すべてが存在しなかった場合の最終的なフォールバック先 |
_partials/ |
再利用できるモジュールとしてのテンプレート。{{ partial "foo.html" . }}または partialCached で呼び出せる |
_markup/ |
Markdown内の画像・リンク・見出しなどの要素のレンダリングを上書き |
_shortcode/ |
コンテンツ内で呼び出せる部品 |
テンプレートの適用順[5]
各ページにどのテンプレートが最終的に使われるかは,「Content Type」「Page Kind」「Content type」「Section」「言語」「出力形式」に応じてHugoが採択します。この項目については一部後述します。
テンプレートの探索優先度については以下リンクなどにルールが詳細にかかれています。
・Page Kind[6]
各ページに紐づくそのページの種別です。以下5つの内から1つ,Hugo が自動で判別します。
| Kind | 説明 |
|---|---|
| home | トップページ |
| section | 特定のセクション(ブログ一覧など) |
| page | 個別のコンテンツページ |
| taxonomy | タグやカテゴリの一覧ページ |
| term | タグやカテゴリの個別ページ |
以下のMethodで見ることができます。
{{ .Kind }}
・Section
content/配下の最上位ディレクトリ名です。
例えばcontent/posts/内のコンテンツはpostsがセクションになります。
・Content Type
Front Matterのtypeにて指定した値です。デフォルトではSectionと同じ値が入り,Sectionがない場合はpageになります。
🔖Front Matter [7]
マークダウンファイルの上部に記載する,メタデータの記述部分をFront Matterといいます。通常TAMLやTOML,JSON形式で記述します。
ここに記述することができるフィールドは以下のサイトにまとめられています。
以下,一部抜粋です。
| キー | 説明 |
|---|---|
| date | ページに関連付ける日付 |
| description | HTMLファイルに変換した際に<meta name="description" content="">に紐付け |
| draft |
trueにすると,下書きファイルとしてビルド対象外にする |
| layout | 適用するレイアウトを指定 |
| summary | 概要テキスト |
| title | ページのタイトル |
| type | コンテンツタイプ(Sectionを上書きする際に指定する) |
| weight | ソート順を制御する整数。小さいほど先に表示 |
| lastmod | 最終更新日 |
また,自分でカスタムキーを追加することもできます。
この場合,以下のように[params]の下に追加します。(一応なくても問題ないですが,カスタムしたものと判別をつけるために入れたほうがいいかと思います)
+++
date = '2025-05-31T07:00:11Z'
draft = true
title = 'Test Page'
[params]
customvalue = 'ABCD'
+++
カスタムキーは以下のMethodで呼び出すことができます。
・Params[8]
まず.Paramsを見て,なければグローバル設定の.Site.Paramsも探します。どちらにもない場合,nullを返します
{{ .Params.customvalue }}
・Param[9]
paramメソッドを使うと,動的にキー名を渡すことができます。
{{ .Param "customvalue" }}
🏗️サイトのビルド
hugoまたはhugo serverコマンドを実行することで静的ファイルをビルドすることができます。
コマンドの違いは以下の通りです。
他にもサブコマンド及びオプション含めてさまざまありますので,詳細はドキュメントを確認ください。
また,ビルドした静的サイトを Github Pages などのサービスと連携してサイトをホストしたい場合もあるかと思います。ここらの手順やサンプル設定については Hugo のサイトにて手順が案内されていますので,そちらを参考にしてみてください。
🧰Method[13]
ここまでで何度か出ているものですが,{{ ... }}を使った記述をすることで,動的に値を参照・加工する Method を使用することができます。
用意されている Method の詳細についてはこちらを参考にしてください。
以下はメソッドの一例です。
| メソッド | 説明 |
|---|---|
| {{ .Title }} | ページのタイトルを取得 |
| {{ .Date }} | Front Matterのdateを取得 |
| {{ .Permalink }} | ページのURLを取得 |
| {{ .Summary }} | ページの要約部分を返す。Front Matterのsummaryを取得 |
| {{ .Site.Params.xxx }} | 設定ファイルのparams以下に定義した値を取得 |
| {{ .Site.Title }} | サイト全体のタイトルを取得 |
| {{ .Site.BaseURL }} | baseURLを取得 |
似たもので Function もあります。
🔗URLまわり
おまけ程度の節ですが,URLについてです。
各ページのURLを設定する方法としては,以下の選択肢があります
-
Front Matter に記述するもの
- url
- aliases
- slug
-
設定ファイルに記述するもの
- permalinks
url
Front Matterに記述することで,そのページの公開URLをルートから一括で指定します。
+++
url = "test/page"
+++
この場合,各パスのアクセス可否は次のようになります。
-
http://<domain>/post/test-page(フォルダパス):❌NG -
http://<domain>/test/page(urlで指定したパス):⭕OK
このように,urlではフォルダ構成に関係なく任意のパスを設定できます。
aliases
aliasesにページの旧URLを設定することで,新URLへ自動リダイレクトを行うことができます。
相対パスの場合,そのmdファイルが存在する位置を起点としますので,意図しない動作になることがあります。そのため,できるだけ絶対パスで書くようにします。
+++
aliases = "/test/page"
+++
上記の例の場合,各パスの表示は以下になります。
-
http://<domain>/post/test-page(フォルダパス):⭕OK -
http://<domain>/test/page(aliasesで指定したパス):⭕/post/test-pageにリダイレクト
生成されるリダイレクトページ
<!DOCTYPE html>
<html lang="en-us">
<head>
<title>http://localhost:1313/post/test-page/</title>
<link rel="canonical" href="http://localhost:1313/post/test-page/">
<meta name="robots" content="noindex">
<meta charset="utf-8">
<meta http-equiv="refresh" content="0; url=http://localhost:1313/post/test-page/">
</head>
</html>
古いURLを転送する場合に利用することが多いでしょうか
slug
slugはURLの最後の部分(slug)のみを変更します。
+++
slug = "test/page"
+++
上記の例の場合,各パスの表示は以下になります。
-
http://<domain>/post/test-page(フォルダパス):❌NG -
http://<domain>/test/page(slugで指定したパス):❌NG -
http://<domain>/post/test/page(フォルダパス+slug):⭕OK

構造に沿った形で名前だけ調整したいときに使えます。
permalinks [14]
より柔軟なURL構成が求められる場合,設定ファイルでpermalinksを使うことで,URLパターンを記述することもできます。
例えば以下の構成,設定を想定します。
content/
├── posts/
│ ├── bash-in-slow-motion.md
│ └── tls-in-a-nutshell.md
├── tutorials/
│ ├── git-for-beginners.md
│ └── javascript-bundling-with-hugo.md
└── _index.md
[permalinks]
[permalinks.page]
posts = '/articles/:year/:month/:slug/'
tutorials = '/training/:slug/'
[permalinks.section]
posts = '/articles/'
tutorials = '/training/'
この場合,ビルド後の構造は以下のようになります
public/
├── articles/
│ ├── 2023/
│ │ ├── 04/
│ │ │ └── bash-in-slow-motion/
│ │ │ └── index.html
│ │ └── 06/
│ │ └── tls-in-a-nutshell/
│ │ └── index.html
│ └── index.html
├── training/
│ ├── git-for-beginners/
│ │ └── index.html
│ ├── javascript-bundling-with-hugo/
│ │ └── index.html
│ └── index.html
└── index.html
ファイル単位ではなくセクション単位でURLルールを定義したい際に使うことができます。
上記の設定例はHugoのドキュメントからそのまま引用したものです。詳細は 公式ページ を参照してください。
🌐他参考サイト
Discussion