Hugoのテーマフォルダ(layouts/)の内部には、baseof.htmllist.html など様々な名前のHTMLファイルが格納されています。

「どのファイルがどのページの表示に使われているの?」
「カスタマイズのために新しいテンプレートを作りたい場合はどこに置けばいい?」

そんなテーマ開発における疑問を解消するために、主要なレイアウトファイルの役割と、Hugoがテンプレートを選ぶ仕組みである**「Lookup Order(優先順位)」**について分かりやすく解説します!


1. 📂 layouts/ (直下)

【モダン構成(Modern)】
最新のHugoでは、ここにメインのテンプレートを置くのが標準的です。
フォルダ階層が浅く、直感的に管理できます。

📄 baseof.html

サイトの「骨格」 です。

📄 page.html (旧: single.html)

「記事ページ」の中身 です。

  • 通常の記事(/posts/hello-world/ など)を表示するときに使われます。
  • タイトルや本文の表示処理を書きます。
  • 旧バージョンでは _default/single.html_default/page.html と呼ばれていました。
  • イメージ: 記事の原稿用紙📝
  • 【Step 4】記事を流し込む!Single(Page)テンプレート

📄 list.html

「一覧ページ」の中身 です。

  • 記事一覧、カテゴリー一覧、タグ一覧などに使われます。
  • {{ range ... }} で記事をループして表示します。
  • 旧バージョンでは _default/list.html と呼ばれていました。
  • イメージ: 目次📚

📄 index.html

「トップページ」専用 のテンプレートです。

📄 404.html

「404 Not Found」 ページです。


2. 📂 layouts/partials/

「部品」 を入れるフォルダです。

  • ヘッダー、フッター、パンくずリストなど、共通パーツを置きます。
  • 呼び出し: {{ partial "header.html" . }}

3. 📂 layouts/_markup/

Markdown の変換ルール(Markdown Render Hooks) をカスタマイズするフォルダです。

  • 通常、記事内のMarkdown(リンク []() や画像 ![]() 、テーブルなど)はそのまま標準的なHTMLタグに変換されますが、ここで変換時の「タグの構造(出力)」を自由に上書き定義できます。Hugo v0.146.0以降のモダンな構成では、_defaultフォルダを介さず直接 layouts/_markup/ に配置します。
  • 例: テーブルを <div class="table-wrapper"> で囲んでスマホ用に横スクロール可能にしたい場合、ここに render-table.html を作成して構造を記述します。
  • 詳しい書き方や仕組みについては、専用の解説記事 【拡張】Markdownの変換ルールを自在に操る(Markdown Render Hooks) をご覧ください。

4. 【参考】従来の構成 (layouts/_default/)

古い既存テーマを触る際によく見かけるのが、 layouts/_default/ というフォルダです。
これはHugo v0.145以前の伝統的な構成です。

  • layouts/_default/single.htmlpage.html 👉 新方式の layouts/page.html と同じ
  • layouts/_default/list.html 👉 新方式の layouts/list.html と同じ
  • layouts/_default/terms.html 👉 新方式の layouts/terms.html と同じ

Hugo v0.146.0 の Modern Template System の導入により _default フォルダは非推奨となりルート階層へ統合されました。実務で古いテーマを触る時は、「あ、これは従来方式だな」と思い出せればOKです!
(機能的にはどちらも正しく動作します)


【応用】Hugoはどうやってファイルを選んでいるの?(Lookup Order)

Hugoは、表示したいページの種類に合わせて、以下の順序でテンプレートを探します(上にあるものほど優先)。

1. トップページ (/)

優先順探すファイル (Modern)説明
1layouts/index.htmlトップページ専用
2layouts/home.htmlホーム専用
3layouts/list.html汎用のリスト

2. 記事一覧ページ (/posts/)

優先順探すファイル (Modern)説明
1layouts/posts/list.htmlpostsセクション専用のリスト
2layouts/section.htmlセクション専用のリスト
3layouts/list.html汎用のリスト

3. 記事個別ページ (/posts/my-post/)

優先順探すファイル (Modern)説明
1layouts/posts/page.htmlposts専用の記事ページ
2layouts/page.html汎用の記事ページ

これを知っていると、カスタマイズが自在になります!


Q&A: よくあるカスタマイズの疑問

Q. トップページだけヘッダーを変えたい時は?

(以下変更なし)

baseof.html は共通ですが、中身をページごとに変える方法はいくつかあります。

方法1: if 文を使う(お手軽)

「もしトップページならA、それ以外ならB」という条件分岐を書きます。

<header>
  {{ if .IsHome }}
    <!-- トップページだけで表示したい豪華なヘッダー -->
    <h1>ようこそ!私のブログへ</h1>
  {{ else }}
    <!-- それ以外のページ用のシンプルなヘッダー -->
    <p>ブログタイトル</p>
  {{ end }}
</header>

方法2: block を使う(上級者向け)

main ブロックと同じように、ヘッダーもブロック化してしまう方法です。

  1. baseof.html で、ヘッダー部分を {{ block "header" . }} ... {{ end }} で囲む。
  2. index.html (トップページ用)の中で {{ define "header" }} を使い、トップページ専用のヘッダーを上書き定義する。

こうすると、index.html がある時だけヘッダーが差し替わります。

補足:

  • define しなかったページでは、元の baseof.htmlblock の中身(デフォルトのヘッダー)がそのまま使われます。便利ですね!

Q. そもそも baseof.html をページごとに分けられないの?

できますが、少し上級者向けです。
例えばトップページ用に layouts/home/baseof.html を作れば、それが優先されます。
でも、ファイルが増えて管理が大変になるので、最初は 「1つの baseof.htmlifblock で制御」 がオススメです。


その他のQ&A

Q. 404.html がないとどうなる?

Hugoが内蔵している「デフォルトの404ページ」が表示されます。
真っ白にはなりませんが、英語のシンプルなページなので、やはり自作した方が親切です。

Q. 「テーマ内のテンプレート」って具体的にどれ?

themes/テーマ名/layouts/ の中にあるファイルのことです。
themes/my-tutorial-theme/layouts/ がそれに当たります(このサイトで使用しているテーマの場合)。

  1. プロジェクト直下の layouts/ (あなたが作ったファイル)
  2. themes/my-tutorial-theme/layouts/ (テーマにもともとあるファイル)

この優先順位のおかげで、テーマのオリジナルファイルを直接書き換えることなく、自身の環境のルートディレクトリにある layouts フォルダに同じ名前のファイルを作るだけで安全に「デザインの上書き(カスタマイズ)」が実現できる仕組みになっています!


テンプレートの役割と優先順位を理解して自在にカスタマイズ

主要なテンプレートファイルがそれぞれどのページに対応しているか(単一記事なら page.html 、一覧なら list.htmlなど)を把握しておくと、修正したい箇所がすぐに見つかるようになります。
さらに、HugoがどのURLに対してどのテンプレートを適用するか(Lookup Order)を理解すれば、「特定のカテゴリーの時だけデザインを変える」などの高度なレイアウト分岐も格段にやりやすくなります。