Hugo + Cloudflare Pages でブログを始めて1週間の運用Tips で「ハマった話」を軽く触れましたが、運用を続けるほど詰まりポイントは増えていきました。今回はそれの拡張版、実際に詰まった5つのことを、対処法とセットで書き残しておきます。

似た構成で運用予定の方の参考になれば。

詰まり①: 記事をプッシュしたのに反映されない(buildFuture の罠)

これは累計4回踏み抜いた最頻トラブル。

date: 2026-04-26T14:00:00+09:00
draft: false

このように書いた記事をプッシュしたのに、サイトに出てこない。「あれ、ビルド失敗した?」「Cloudflareがおかしい?」と Cloudflare Pages のログを見ても異常なし。

原因は buildFuture = false(hugo.toml デフォルト)と 時刻の比較でした。

見抜き方

「日付」だけ見ると今日に見えるのに、時刻を含めると未来扱いになっているケース。

記事の date:        2026-04-26T14:00:00+09:00
                    = 2026-04-26T05:00:00 UTC
ビルド時の現在UTC:   2026-04-26T03:30:00
                    → 1時間半未来 → 除外!

JST午後の時刻を入れたまま日本の早朝にプッシュすると、UTCではまだ前日扱いになっていて引っかかります。

対処法

私のルール:

  • 時刻は JST 05:00〜09:00 で固定 にする(UTC換算でも前日扱いにならない)
  • 確実なのは 時刻省略: date: 2026-04-26 だけ書けば 00:00:00 JST になる

最近はこのルールに固定して以来、踏まなくなりました。

詰まり②: 記号入りカテゴリ名で404

「AI & Claude Code」というカテゴリ名のリンクがすべて404になる現象。

表示: AI & Claude Code
リンク先: https://yakiimo-tech.com/categories/ai-claude-code/
       → 404 Not Found

原因

トップページのテンプレートで urlize を使ってURLを組み立てていました。

<a href="{{ printf "categories/%s/" (index . 0 | urlize) | relURL }}">

urlize "AI & Claude Code"ai-claude-code(ハイフン1つ)を返します。 ところが Hugo が実際に作るフォルダai--claude-code(ハイフン2つ。& が空白2つに置換される影響)。 → 不一致で404、というカラクリ。

対処法

URL を手動で組み立てるのをやめるのが鉄則。

{{ with ($p.GetTerms "categories") }}
  {{ $cat := index . 0 }}
  <a href="{{ $cat.RelPermalink }}">{{ $cat.LinkTitle }}</a>
{{ end }}

.GetTerms で取得した taxonomy ページの .RelPermalink を使えば、Hugo に組み立てを任せられます。記号でも日本語でも安全。

詰まり③: ローカルで hugo が実行できない(Windows Device Guard)

ローカルでビルド確認したくて hugo --quiet を叩くと、こうなりました。

'C:\Users\sakae\AppData\Local\...\hugo.exe' は組織の Device Guard ポリシーによってブロックされました。

Windows 11 の Device Guard(Windows Defender Application Control)が、署名のない実行ファイルをブロックする設定になっていたのが原因。winget でインストールした Hugo 単独バイナリは未署名でした。

対処法(私の運用)

ローカルビルドは諦めて Cloudflare Pages 側のビルドに任せることにしました。

  • git push → Cloudflare Pages がビルド → 公開
  • ローカルでは Markdown と front matter だけチェック
  • 確認は本番サイトでハードリロード

これで運用は回ります。Hugo を IT 管理外で動かすには、署名済みビルド版(Hugo Extended の MSI 版など)を別途検討する必要があります。

詰まり④: 修正したのに古いページが見える(キャッシュ残留)

プッシュ → デプロイ完了通知 → サイトを開く → 古いまま

これが何度もありました。原因は2層のキャッシュ:

  1. Cloudflare のエッジキャッシュ(数分残ることがある)
  2. ブラウザのローカルキャッシュ(特に強い)

対処法

確認するときは以下のいずれか:

# curl でキャッシュバスター付き確認
curl -sI "https://yakiimo-tech.com/posts/foo/?v=$(date +%s)"

ブラウザなら:

  • Ctrl+F5(ハードリロード)
  • またはシークレットウィンドウで開く(最も確実)

特に AI に「サイトを見て確認して」と頼むタイプのワークフローでは、AI 側にもキャッシュがある点に注意。15分くらい古い情報を返すことがあります。クエリパラメータでキャッシュバスターを付けると確実です。

詰まり⑤: git push だけでは Cloudflare Pages のビルドが走らない時がある

普段は git push すれば Cloudflare Pages の Webhook が拾ってビルドが走るはずですが、反応しないことが何度かありました

具体的には: プッシュから5分待っても新記事が出てこず、Cloudflare Pages のダッシュボードを見ても新しいデプロイが始まっていない。

対処法

GitHub Actions でスケジュールリビルド用ワークフローを仕込んでおいて、手動でも叩けるようにしてあります。

gh workflow run "Scheduled Hugo Rebuild"

これで GitHub Actions が Cloudflare Pages のデプロイフックを叩き、強制的にビルドを走らせる仕組み。「反映されない」と感じたらまずこれを叩く、という運用にしてからストレスが激減しました。

毎日定時にも自動で走らせているので、未来日付の予約投稿が日付経過後にちゃんと拾われるという副次効果もあります。

まとめ: 詰まりは「型」、対処法を手元に置く

5つのうち①②④は運用フローを決めれば再発しなくなるタイプ、③⑤は回避策を用意しておくタイプです。

詰まり種別対処の本質
①buildFutureフロー固定時刻ルールを統一
②カテゴリ4041回直して終わりテンプレ書き換え
③Device Guard諦めて回避ローカルビルド断念
④キャッシュ確認手順固定クエリパラメータ習慣化
⑤デプロイ不発フォールバック用意手動トリガー仕込み

ブログ運用は「うまくいくケース」より「うまくいかないケースをどう対処するか」のほうが、毎日の精神衛生に効いてきます。新規でブログを始める方の参考になれば嬉しいです。

次回は、Cloudflare Pages のデプロイログから過去のビルド失敗を遡って調べる方法を書く予定です。