← Blog

11ty と Liquid を雑に話す

Mar 21, 2026 · 5 min

動機

ホームページをリニューアルする際に、React エコシステムから脱却して、11ty に変更しました。11ty は Liquid というマークアップ言語を使って記述することができます。
11ty はその他にも複数のマークアップ言語に対応しているのですが、HTML を素で記述しているような書き味で、尚且つ辛い部分だけ楽したいという自分の要求をミニマムに実現可能なのが Liquid でした。

近い将来 11ty, Liquid のことはほぼほぼ忘れてしまうはずなので、何が実装されているのか、とっかかりを理解する上で必要な知識を書き記しておこうと思います。

11ty

eleventy.config.js このファイルが 11ty プロジェクトの設定を担っています。

return {
  dir: {
    input: "src",
    includes: "_includes",
    data: "_data",
    output: "_site",
  },
};

細かい部分は省きますが、どのフォルダをどう扱うかというのを定義しています。

  • input

ここに指定した場所がトップレベルディレクトリとして認識されます。
配下のファイルは HTML への変換対象であるテンプレートファイルとして認識されます。

  • includes

テンプレートファイルから参照するファイル (partials, extensions, ...) として認識されます。
ここに置いたファイルは単体ではテンプレートファイルとしては認識されません。
また SSG の慣習として _ が prefix についたフォルダはエンジン側からテンプレートとしては認識されなくなるようです。

  • data

各種テンプレートから参照可能なグローバルデータとして認識されます。
includes 同様に、ファイル単体ではテンプレートファイルとしては認識されません。
付加情報を記載しているので、includes の項目を先に見てください。

  • output

生成された HTML の出力先として認識されます。
また、今回で言う src つまり、トップレベルディレクトリの外にあるファイルで生成物に含めたいようなもの、例えば public, css なども output に指定したフォルダに配置する必要があります。

eleventyConfig.addPassthroughCopy("public");

API を利用することで、そういったフォルダをビルド時に output へ出力することができます。
上記のように指定した場合は _site/public のように配置されます。

Liquid

Shopify が提供するマークアップ言語です。OSS として提供されています。

https://github.com/Shopify/liquid

雰囲気さえ分かれば書けてしまうぐらいには容易です。

https://liquidjs.com/playground.html

これを開くと、Liquid のマークアップ構文で書かれたテンプレートがどのように HTML に変換されるかが分かります。
覚えることは 2 つぐらいで良くて、

{% %}

ロジックは上記のように記述し、

{{ }}

出力したい場合はこのように記述します。もう少し踏み込んでいきます。
_data フォルダに family.json を配置したとします。

family.json
{
  "people": [
    "alice",
    "bob",
    "carol"
  ]
}

そして、下記のように記述する。

<ul>
{%- for person in family.people %}
  <li>
    <a href="{{person | prepend: "https://example.com/"}}">
      {{ person | capitalize }}
    </a>
  </li>
{%- endfor%}
</ul>

変換後の HTML はこうなる。

<ul>
  <li>
    <a href="https://example.com/alice">
      Alice
    </a>
  </li>
  <li>
    <a href="https://example.com/bob">
      Bob
    </a>
  </li>
  <li>
    <a href="https://example.com/carol">
      Carol
    </a>
  </li>
</ul>

また、prependcapitalize などをフィルターと言います。
CLI を叩いている時のことを思い出してください。

cat foo.txt | grep bar

これは出力結果を grep に流して bar というテキストの存在する行を出力しますが、Liquid も同様です。
person 変数に格納されたテキストの出力結果を prepend や capitalize に流しているというわけです。

https://liquidjs.com/filters/overview.html

このように、たくさんの built-in filters が存在するので、ロジックを書く前に一度ここを見るのが良いと思います。
また、11ty では独自に filters を記述できるようになっています。

eleventy.config.js
export default function (eleventyConfig) {
  // 省略
  eleventyConfig.addFilter("formatDate", (dateStr) => {
    const date = new Date(dateStr);
    return date.toLocaleDateString("en-US", {
      month: "short",
      day: "numeric",
      year: "numeric",
    });
  });
  // 省略
}

例えば、built-in の date filters が使いにくかったので、ブログ記事の日付用に自前で書いたやつです。