2026年04月26日
OTTAN.JP
iPhone · Mac · Windows Tips
Blog

【2026年版】Decap CMS(旧Netlify CMS)+ Hugo の Page Bundles 対応

By ottanjp 3 min read 更新 2026.04.22

🔁 2026年リライト版 この記事は2020年4月に公開した「Netlify CMS + HugoでPage Bundles(コンテントと画像を同じ場所に配置)に対応する」を、2026年時点の Decap CMS(2023年の Netlify CMS フォーク / リネーム)前提で書き換えたものです。

2026年の状況 — Netlify CMS は Decap CMS にフォークされた

Netlify CMS は、2023年2月に元運営元 Netlify の開発撤退にともない、コミュニティで Decap CMS としてフォーク・改名されました。パッケージ名も netlify-cms から decap-cms へ移行しています。

  • : https://unpkg.com/netlify-cms@^2.x/dist/netlify-cms.js
  • : https://unpkg.com/decap-cms@^3.x/dist/decap-cms.js

バックエンド API やカスタマイズポイントはほぼ互換で、移行は基本的にスクリプトURLとバージョン指定の書き換えだけで済みます。本記事では Decap CMS 3.x + Hugo 0.140+ を前提に、Hugo Page Bundles 対応を解説します。

目指すディレクトリ構造

記事ごとに画像ファイルをまとめる Page Bundles の構成です。

.
├── archetypes
├── assets
├── config.yaml
├── content
│   └── posts
│       └── 2026
│           ├── 04
│           │   └── my-post/
│           │       ├── index.md
│           │       └── cover.png
│           └── 05
│               └── another-post/
│                   ├── index.md
│                   └── diagram.png
├── layouts
├── static
│   └── admin
│       ├── config.yml
│       └── index.html
└── themes

記事は leaf bundleindex.md をもつディレクトリ)として配置します。Decap CMS のコレクション設定で path{{slug}}/index にするのがポイントです。

Decap CMS のスクリプト読み込み(2026年版)

static/admin/index.html:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Content Manager</title>
</head>
<body>
  <script src="https://unpkg.com/decap-cms@^3.8.0/dist/decap-cms.js"></script>
</body>
</html>

Decap CMS の config.yml(Page Bundles 対応)

static/admin/config.yml:

backend:
  name: git-gateway
  branch: main  # 2020年当時は master だったが現在は main が標準

media_folder: static/images
public_folder: /images

publish_mode: editorial_workflow

collections:
  - name: blog
    label: Blog
    folder: content/posts
    create: true
    slug: '{{fields.slug}}'

    # ★ここが Page Bundle の肝
    path: '{{year}}/{{month}}/{{slug}}/index'

    # 記事内の画像を同じディレクトリに保存
    media_folder: ''
    public_folder: ''

    preview_path: 'posts/{{year}}/{{month}}/{{slug}}/'
    identifier_field: title
    fields:
      - { label: Title, name: title, widget: string }
      - { label: Publish Date, name: date, widget: datetime, format: 'YYYY-MM-DD' }
      - { label: Tags, name: tags, widget: list, required: false }
      - { label: Draft, name: draft, widget: boolean, default: false }
      - { label: Body, name: body, widget: markdown }
      - { label: Slug, name: slug, widget: string }

各フィールドの役割:

path: '{{year}}/{{month}}/{{slug}}/index'

folder を起点に、上記パスのマークダウンファイル(.md は自動付与)が生成されます。末尾が /index になっているのがポイント。これで Hugo が leaf bundle として認識します。

content/posts/2026/04/my-post/index.md

media_folder: '' / public_folder: ''

どちらも空文字列にすると、記事 Markdown と同じディレクトリに画像ファイルが配置される ようになります。

結果、画像は:

content/posts/2026/04/my-post/cover.png

Markdown には:

![](cover.png)

という 相対パス で埋め込まれ、Hugo がレンダリング時に各ページバンドル内の資産として適切に解決してくれます。

Hugo 側の対応(2026年)

Hugo 0.140+ では、リソース画像の取り扱いに imageProcessingresources.Get を使えます。layouts/_default/_markup/render-image.html で画像レンダリングをカスタマイズする例:

{{ $image := .Page.Resources.GetMatch .Destination }}
{{ if $image }}
  {{ $small := $image.Resize "800x webp q80" }}
  <img src="{{ $small.RelPermalink }}" alt="{{ .Text }}" loading="lazy">
{{ else }}
  <img src="{{ .Destination }}" alt="{{ .Text }}">
{{ end }}

これで、Decap CMS から投稿された画像は WebP 化・リサイズされた上で配信されます。

ローカルテストも忘れずに

Decap CMS をローカルで動かす方法は ローカルホストでDecap CMS(旧Netlify CMS)をテストする を参照してください(記事タイトルは旧称のまま残しています)。

参考

Comments
comments powered by Disqus