本文へスキップ
Website Boilerplate

テンプレート

本ページは、src/ 配下のページと部品を書くときの規約を扱います。ページデータの受け渡し、layout プロパティによるレイアウトの指定、レイアウトチェイニングの組み方までを扱います。

YAML frontmatter でページデータを渡す

MDX テンプレートは、ファイル先頭の --- フェンスで囲んだ YAML block に Eleventy のページデータを書きます。Markdown 界隈で見慣れた frontmatter そのままの形です。

---
layout: post
title: はじめてのサイト
description: 本ボイラープレートで作った最初のページ
---

# はじめてのサイト

本文はここから書きます。

YAML でスカラ、マッピング、配列で表現できる値はそのまま置けます。layout はプリセット下では必ず使う項目、title description は多くの partial (ogp.mdx など) が参照する項目です。

MDX プロセッサ (Sätteri) は先頭の --- フェンスを検出して frontmatter block を切り出すところまでを担い、その内側を YAML としてパースするのは本プラグインの担当です (依存の yaml パッケージを使います)。パース結果は Eleventy の 11ty.js テンプレートに export const data = ... として引き渡され、ページ側からは Eleventy 標準の frontmatter と同じ感覚で扱えます。

.jsx / .tsx テンプレートは JSX 構文の都合で --- を書けないため、これらのみ従来通り export const data = { ... } を使います。MDX 側でも export const data を書けますが、frontmatter と併用すると重複 export になるため、いずれか片方に絞ります。

layout プロパティで親を指定する

各ページは frontmatter の layout に親テンプレートの名前を書きます。値は _includes/ からの相対パス (拡張子を除く) です。

---
layout: post # src/_includes/post.mdx を親にする
---

親テンプレートも layout を持てるため、複数段のチェーンが組めます。

レイアウトチェイニングの組み方

scaffold のデフォルトは次の 3 段構成です。

src/index.mdx  →  src/_includes/post.mdx  →  src/_includes/base.mdx
   (ページ)          (記事のラッパ)              (HTML の骨格)

各レイアウトは、子テンプレートから受け取った HTML を eleventy.content として持ちます。これを dangerouslySetInnerHTML で埋め込むことで、子の出力を親の JSX ツリーに差し込みます。

ルートレイアウト (_includes/base.mdx)

HTML の全体骨格を担います。<html>, <head>, <body> を書き、<main> に子の内容を差し込みます。

import { eleventy } from "@tuqulore-inc/eleventy-preset/eleventy";

<html lang={eleventy.locale ?? "ja"}>
  <head>
    <title>
      {eleventy.title && `${eleventy.title} | `}
      {eleventy.site.name}
    </title>
    <link rel="stylesheet" href="/main.css" />
  </head>
  <body>
    <main dangerouslySetInnerHTML={{ __html: eleventy.content }} />
  </body>
</html>

中間レイアウト (_includes/post.mdx)

コンテンツのラッパ (<article class="prose"> など) を担い、base を親に指定します。

---
layout: base
---

import { eleventy } from "@tuqulore-inc/eleventy-preset/eleventy";

<article class="prose" dangerouslySetInnerHTML={{ __html: eleventy.content }} />

使い分けの目安

  • ルートレイアウトは 1 つに集約し、<html> 骨格の重複を避けます。
  • 中間レイアウトはページ種別ごとに増やせます (記事は post、目次ページは list など)。
  • 各ページは中間レイアウトを指し、ルートレイアウトを直接指さない構成が保守しやすいです。

partial を差し込む

_includes/partials/ に置いた MDX / JSX は、レイアウトから import して JSX 経由で呼び出します。

import Header from "./partials/header.mdx";
import Footer from "./partials/footer.mdx";

<Header />
<main dangerouslySetInnerHTML={{ __html: eleventy.content }} />
<Footer />

partial 側は自身の props と、Data Access で扱う eleventy シングルトンから必要な値を取ります。呼び出し側から props を渡していく必要はありません。

Island を差し込む

クライアント側で動かしたい要素は、src/**/*.client.jsx に置き、MDX から <Island> で括って埋め込みます。

import { Island } from "@tuqulore-inc/eleventy-preset/island";
import Counter from "./counter.client.jsx";

<Island component={Counter} on="interaction" initial={5} />

<Island> の設計と粒度の目安は Plugins / eleventy-plugin-preact-island を参照してください。