a-blog cms のTwigテーマ化のためのEleventy + Nunjucks + Vite静的HTML制作環境
この記事は a-blog cms Advent Calendar 2025 の 7日目の記事です。
昨年12月、名古屋で開催された「Stack Nagoya Fes」でも少しお話しさせていただいたのですが、「静的HTMLを最初に作る制作フローにするなら、どのCMSが良いの?」という話題の中で、a-blog cms はおすすめですよ、という話をし、記事にもしました。
参照:静的HTMLを最初に作る制作フローにするなら、a-blog cms がおすすめ
今回は、その前段となる 「そもそも a-blog cms のテーマ化を見据えた静的HTMLをどうやって作るか」 について、最近個人的にしっくりきている Eleventy + Nunjucks + Vite の組み合わせについて備忘録がてら書いておこうと思います。
はじめに
a-blog cms のテーマ制作フローは案件によって様々だと思いますが、ある程度の規模になると、いきなりCMS上で組み始めるよりも、一旦静的HTMLとしてガッツリ作り込んでからテーマ化する、というケースが多いのではないでしょうか。
この「静的HTML制作」の環境、みなさんどうされていますか?
私もいろいろ試行錯誤してきたのですが、 「最終的に a-blog cms のテーマにする」 というゴール・制約を考えたとき、2025年現在では Eleventy + Nunjucks + Vite が一番バランスが良さそう、と感じています。
なぜこの組み合わせなのか
1. Nunjucks と a-blog cms の親和性
これが最大の理由です。
最新のa-blog cms 3.2からは、Twig でテーマが構造できるようになりました。
特に、{% include %} でパーツを読み込んだり、ベースレイアウトを定義して block で中身を差し替えたりといったコンポーネント指向・継承の考え方が、Nunjucks でそのまま実現できます。
例えば、Nunjucks でこう書くと:
{# Nunjucks: layout/base.njk #}
<!DOCTYPE html>
<html lang="ja">
<body>
{% include "header.njk" %}
<main>
{% block content %}{% endblock %}
</main>
{% include "footer.njk" %}
</body>
</html>
これが a-blog cms(Ver 3.1.x までの標準的な書き方)だとこうなります:
<!-- BEGIN_MODULE Template -->
@include("/include/header.html")
<!-- END_MODULE Template -->
<main>
<!-- ここに各ページの内容が入る -->
</main>
<!-- BEGIN_MODULE Template -->
@include("/include/footer.html")
<!-- END_MODULE Template -->
記法こそ違いますが、「ヘッダーとフッターをインクルードする」「メイン部分を差し替える」という構造自体は同じです。
Nunjucks で作ったディレクトリ構造(_includes, _layouts など)をそのまま a-blog cms のテーマディレクトリ(include 等)にマッピングしやすいので、「静的HTMLを作ったはいいけど、CMSに組み込むときに構造を作り直し…」 という課題を減らせます。
そして、a-blog cms 3.2からは、TwigでNunjucksと同じ構造を実現できます。
{# Twig: layout/base.twig #}
<!DOCTYPE html>
<html lang="ja">
<body>
{% include "header.twig" %}
<main>
{% block content %}{% endblock %}
</main>
{% include "footer.twig" %}
</body>
</html>
2. Eleventy のシンプルさ
Nunjucks が使える静的サイトジェネレーター(SSG)は他にもありますが、Eleventy は「余計なことをしない」ところが気に入っています。
ファイル構造が素直に出力されるので、a-blog cms のテーマディレクトリ構造を意識しながらディレクトリを切れば、そのまま綺麗な形で出力されます。
3. Vite の圧倒的な開発体験
そしてこれです。Vite。
eleventy-plugin-vite を使うことで、Eleventy のビルドプロセスに Vite を噛ませることができます。
これにより、開発中は HMR(Hot Module Replacement)が効くようになり、CSSやJSを変更するとブラウザが瞬時に更新されます。
実際のセットアップ
備忘録として、構成を少し紹介します。
ディレクトリ構造
.
├── src/
│ ├── _layouts/ # レイアウトファイル
│ ├── _includes/ # インクルードファイル
│ ├── css/ # CSS
│ ├── js/ # JavaScript
│ └── index.twig # 各ページ
├── _site/ # 出力先(a-blog cmsのテーマの元になる)
├── eleventy.config.js
└── package.json
package.json
2025年12月現在、 Eleventy v3 と eleventy-plugin-vite v7系を使っています。
{
"private": true,
"scripts": {
"dev": "eleventy --serve",
"build": "eleventy"
},
"devDependencies": {
"@11ty/eleventy": "^3.0.0",
"@11ty/eleventy-plugin-vite": "^7.0.0",
"nunjucks": "^3.2.4",
"vite": "^5.0.0"
}
}
eleventy.config.js
ポイントは .twig 拡張子も Nunjucks として処理させてしまう設定です。
a-blog cms のテンプレートは本来 .html ですが、エディタでのシンタックスハイライトや補完を効きやすくするため、開発時は .twig で書いてしまったりもします。
import EleventyVitePlugin from '@11ty/eleventy-plugin-vite';
export default function (eleventyConfig) {
// Viteプラグイン
eleventyConfig.addPlugin(EleventyVitePlugin, {
viteOptions: {
server: {
mode: 'development',
middlewareMode: true,
},
build: {
mode: 'production',
// アセットの出力先などを調整
rollupOptions: {
output: {
assetFileNames: (assetInfo) => {
if (assetInfo.name && assetInfo.name.endsWith('.css')) {
return 'assets/css/[name].css';
}
return 'assets/[name][extname]';
},
},
},
}
},
});
// .twig も Nunjucks として扱う
eleventyConfig.addExtension('twig', {
key: 'njk',
});
return {
dir: {
input: 'src',
output: '_site',
includes: '_includes',
layouts: '_layouts',
},
markdownTemplateEngine: 'njk',
htmlTemplateEngine: 'njk',
};
}
a-blog cms テーマ化への橋渡し
こうして作った静的HTMLを、いざ a-blog cms に組み込む際は、以下の手順で進めます。
-
_siteに書き出されたHTMLを確認する。 - 3.2より前のバージョンであれば、Nunjucks の
{% include %}などを、a-blog cms の@includeやモジュール記法に書き換えが必要ですが、 3.2以降であれば、Twigで同じ構造を実現できます。
まとめ:適材適所でツールを選ぼう
静的HTMLを先に作るフローの場合、WordPress だとブロックエディタとの兼ね合いで「二度手間」になりがちで推奨されなくなってきましたが、a-blog cms のようなCMSであれば、静的HTMLからのテーマ化は依然として有効なアプローチだと思います。
その際の相棒として、 Eleventy + Nunjucks + Vite 、個人的にはかなりおすすめです。静的に書いたファイルを出力したファイルでもそのままCMSのテーマディレクトリに移動させることができますし、開発元ファイルをTwig 形式で書いたものも比較的簡単にテーマに組み込むことができます。
もし「もっと良い構成あるよ!」とか「ここはこうした方が…」というのがあれば、ぜひ教えてください。
今年も Advent Calendar で皆さんの知見が見られるのを楽しみにしています!
最後に: ベースファイルをGitに入れておきました
あくまで自己判断での利用にして欲しいのですが、ベースファイルをGitに入れておきました。参考にしてみてください。
Discussion