Hugo で Tailwind CSS を使うための設定
まえがき
かつて静的サイトジェネレータの Hugo で Tailwind CSS を使おうとするとうまくいかないことがありました。
たとえば hugo server
で起動中、新しいクラスを付けてホットリロードしたのに見た目が反映されない……ということが、Hugo だと容易に起こります。
また、それを解決するための設定は一筋縄ではいきませんでした。
しかし最近改めて調べてみたら、去年 Tailwind CSS のためだけに新機能が実装されていました。
現在はそう複雑ではない設定で Tailwind CSS を快適に使うことができますので、今後 Hugo を使う方にご紹介したいと思います。
環境
- Hugo: v0.142.0
- Tailwind CSS: v4.0.2
結論
Hugo の開発者の bep 氏が Tailwind CSS 連携のサンプルを作成してくれています。
Tailwind CSS v4 対応のリポジトリは下記です。
結論としてはこれを真似れば終わりですが、確認したところ少しだけ不要な記述が含まれていたので、本記事向けに上記サンプルリポジトリの "TailwindCSS CLI Defer" のパターンで実装しました。私のサンプルリポジトリは下記です。
https://gitlab.com/k1350/hugo-tailwindcss
この後は私なりに何をやっているかの解説を挟んでいきたいと思います。
実装について詳しく
やることは2点です。
- templates.Defer で Tailwind CSS CLI の処理を遅延する
- 適宜 css ファイルのキャッシュを削除する
templates.Defer で Tailwind CSS CLI の処理を遅延する
Hugo で Tailwind CSS CLI を動かすために css.TailwindCSS という機能が存在しますので、これを使います。
package.json の scripts には何も書く必要はありません。@tailwindcss/cli
が dependencies/devDependencies に入っていてインストール済みであればいいです。
全文は長いので サンプルリポジトリ をご参照いただくとして、該当部分だけ下記に抜粋します。
<head>
<!-- 中略 -->
{{ with (templates.Defer (dict "key" "global")) }}
{{ with resources.Get "css/styles.css" }}
{{ $opts := dict
"inlineImports" true
"optimize" (not hugo.IsDevelopment)
}}
{{ with . | css.TailwindCSS $opts }}
{{ if hugo.IsDevelopment }}
<link rel="stylesheet" href="{{ .RelPermalink }}" />
{{ else }}
{{ with . | minify | fingerprint }}
<link
rel="stylesheet"
href="{{ .RelPermalink }}"
integrity="{{ .Data.Integrity }}"
crossorigin="anonymous" />
{{ end }}
{{ end }}
{{ end }}
{{ end }}
{{ end }}
</head>
templates.Defer はブロック内の処理実行をサイト全体のレンダリングが終わるまで遅延させます。
ブロック内では assets/css/styles.css
を取得して Tailwind CSS CLI による処理を行っています。
要するに、サイト全体で使用されるクラスが確定してから Tailwind CSS CLI を動かすことができます。
適宜 css ファイルのキャッシュを削除する
Tailwind CSS CLI の処理を遅延させるだけでも問題なく動くように見えるのですが、text-[<value>]
のように custom value を使ったときなど、特定のケースで画面が更新されない場合があります。
その対策で hugo.yaml で次の設定を行います。
baseURL: 'https://example.org/'
languageCode: 'en-us'
title: 'My New Hugo Site'
module:
hugoVersion:
min: "0.128.0"
mounts:
- source: assets
target: assets
- source: hugo_stats.json
target: assets/notwatching/hugo_stats.json
disableWatch: true
build:
buildStats:
enable: true
cachebusters:
- source: assets/notwatching/hugo_stats\.json
target: styles\.css
まず build.buildStats を有効にします。
これを有効にするとルートディレクトリに hugo_stats.json
というファイルが生成されるようになります。
hugo_stats.json
にはサイト内で使用されている HTML タグ、クラス名、ID 名が記載されます。
次に module.mounts でルートディレクトリの hugo_stats.json
を assets ディレクトリにマウントします。
disableWatch: true
を指定しておくことで、hugo server
中に hugo_stats.json
が変更されるたびに再度リビルドしてしまうことを防止します。
ドキュメントに
When you add a mount, the default mount for the concerned target root is ignored: be sure to explicitly add it.
と書いてある通り、target: assets/notwatching/hugo_stats.json
の設定を追加するとデフォルトの target: assets
へのマウント設定が消えるので、それも追加しています。
最後に build.cachebusters は assets/notwatching/hugo_stats.json
の変更を検知して style.css
のキャッシュを無効化します。
以上を総合すると、hugo server
で HTML タグ、クラス名、ID 名等の変更を検知したら style.css
のキャッシュが消えるようになります。
その結果、クラスの変更が正しく画面に反映されるようになります。
終わりに
インターネット上には「Hugo で Tailwind CSS を使う方法」の解説記事がたくさんあるのですが、Hugo の開発速度が速いため、古いものを参考にするとハマります。
たとえば templates.Defer と css.TailwindCSS は 2024/06/26 にリリースされた Hugo v0.128.0 で追加されたもので、これらの機能が出る前の記事を参考にすると無駄に面倒な設定を行うことになります。
新しい機能を使って快適にサイトを作りましょう!

ちょっと株式会社(chot-inc.com)のエンジニアブログです。 フロントエンドエンジニア募集中! カジュアル面接申し込みはこちらから chot-inc.com/recruit/iuj62owig
Discussion