Content Collections
zfb.config で型付きの Markdown コンテンツコレクションを定義し、ページから読み込む。
コンテンツコレクションとは、プロジェクト設定で宣言した Markdown(または MDX)ファイルのディレクトリです。zfb はビルド時にそのディレクトリをスキャンし、各ファイルのフロントマターをあなたが指定したスキーマに照らしてパースし、ページから呼び出せる getCollection() ヘルパーを通じてエントリを公開します。
コレクションを宣言する
コレクションは zfb.config.ts(または zfb.config.json)の collections キーの下で設定します。各エントリは name と path を持ちます。
export default {
collections: [
{
name: "blog",
path: "content/blog",
},
],
};name は getCollection() に渡す識別子です。path はエントリを格納するディレクトリ(プロジェクトルートからの相対パス)です。zfb はそのディレクトリを走査し、各ファイルをフロントマター付きの Markdown ドキュメントとして扱い、getCollection("blog") を通じてそのエントリを公開します。
加えて、任意の schema フィールドを指定できます。これは JSON Schema のサブセットで、zfb check を実行したときに各エントリのフロントマターを検証します(ビルド自体はこれを強制しません)。サポートされるキーワード(type、properties、items、required、enum)は defineConfig のページに記載されています。フィールドごとの検証を必要としないプロジェクト向けに、[{ name, path }] の形式も引き続きサポートされます。
ページからエントリを読み込む
ページは getCollection() を使ってすべてのエントリを列挙するか、結果を絞り込んで slug で 1 件を特定します。
import { getCollection } from "zfb/content";
export default function BlogIndex() {
const posts = getCollection("blog");
return (
<ul>
{posts.map((post) => (
<li key={post.slug}>
<a href={`/blog/${post.slug}`}>{post.data.title}</a>
</li>
))}
</ul>
);
}import { getCollection } from "zfb/content";
export default function FeaturedPost() {
const featured = getCollection("blog").find((e) => e.slug === "hello-zfb");
if (!featured) return null;
return <featured.Content />;
}getCollection() は同期的です。コンテンツのスナップショット全体は、いずれかの TSX モジュールが走る前に Rust 側で構築され、globalThis.__zfb に埋め込まれます。そのため呼び出し時に I/O は発生せず、引き回すべき await もありません。このサーフェスを支える Rust↔JS ブリッジの契約は安定しており、zfb パッケージとともにバージョン管理されています。
各エントリには、信頼して利用できる 3 つの要素があります。
data— パース済みで検証済みのフロントマター(スキーマに照らして型付けされています)。Content— 本文からコンパイルされたレンダリング可能な React/Preact コンポーネント。<post.のようにレンダリングし、Content components= {. . . } / > componentsprop を通じて要素レベルのオーバーライドを渡します。これは Astro の@astrojs/mdxが公開しているものと同じ契約です。詳細とdefaultComponentsのレシピについては MDX Components を参照してください。slug— ファイル名から導出されます(my-first-post.md→my-first-post)。ネストしたディレクトリはスラッシュ区切りの slug になります。
この関数のシグネチャは getCollection に記載されています。
パースの仕組み
内部では zfb-content クレートが 3 つの仕事をこなします。設定されたディレクトリを走査し、各ファイルの YAML フロントマターをパースし、Markdown/MDX 本文を mdast → JSX ソースのエミッターを通してコンパイルします。コンパイル結果は既存の SWC TSX → JS パイプラインへ渡されます。その結果はエントリごとの JSX モジュールであり、安定した mdx: 指定子でアドレス指定されます。ページレンダラーはそのモジュールを必要に応じて評価し、ページに対して entry.Content として公開します。
コンパイルとサーフェスの契約は安定しています。レンダリング側については MDX Components を参照してください。