EmDashでACFのリピーターを再現する——Field Kitの4ウィジェットと設定例
EmDashのjsonフィールドに入力画面を付けるField Kitの使い方。list・object-form・grid・tagsの設定例、このサイトの実績ページでの実例、ACFとの対応表、できないことをまとめました。

「担当範囲を1行ずつ入れたい」「使用技術をタグで選ばせたい」。WordPressならACF(Advanced Custom Fields)で済む話が、EmDashに移った途端に止まることがあります。EmDashのjsonフィールドは、標準のままだとJSONを手で書く入力欄しか出ないからです。
答えは公式プラグインのField Kitで、jsonフィールドに4種類の入力画面を付けられ、ACFのリピーターに近い使い心地になります。このサイトの実績ページも、使用技術の入力に使っています。
Field Kitはjsonフィールドの入力画面を差し替えるプラグイン
Field Kitが変えるのは管理画面の入力欄だけで、保存されるデータはただのJSONのままです。導入前と導入後で何が違うのか、順に見ていきます。
標準のjsonフィールドは「JSONを手で書く欄」
EmDashのjsonフィールドは、どんな構造のデータでも入る便利な型ですが、入力欄は生のJSONを書くテキストエリアで、カンマや引用符を1つ落とすと保存できません。

上はこのブログ記事自体の「タグ」欄です。記事を書くのは自分なので困りませんが、クライアントに渡す実績やスタッフ紹介の欄がこれだと、更新のたびに問い合わせが来ます。
導入はnpmと設定1行
Field Kitはnpmで入れて、astro.config.mjs の plugins に渡すだけで有効になります(公式ドキュメント)。
npm i @emdash-cms/plugin-field-kitimport emdash from "emdash/astro";
import { fieldKitPlugin } from "@emdash-cms/plugin-field-kit";
export default defineConfig({
integrations: [
emdash({
// database・storage などは省略
plugins: [fieldKitPlugin()],
}),
],
});あとはフィールド定義で widget に field-kit:<ウィジェット名> を書くと、その欄の入力画面が切り替わります。必要な options が足りないときは、入力欄の代わりに設定ミスの警告が出ます。壊れた入力欄で保存してしまう心配はありません。
ネイティブ型とサンドボックス型の違いは、プラグイン形式の選び方(公式)に整理されています。
外してもデータは消えない
Field Kitは既存のjson列にふつうのJSONを書くだけなので、プラグインを外すとその欄は元のJSON入力欄に戻り、データはそのまま残ります。
項目の構成を後から変えたときも安心です。保存済みのデータにある知らないキーは、次に保存したときも消さずに残す仕様なので、古い項目を書いた行がいきなり壊れることはありません。
4つのウィジェットは「データの形」で選ぶ
どのウィジェットを使うかは、見た目より、保存したいデータの形で決めます。ポイントは4つです。
- 同じ形の行を何件でも足したい → list
- 項目が決まった1つのまとまり → object-form
- 行と列の表を埋めたい → grid
- 文字列をいくつか並べたい → tags

ウィジェット | 向いている項目 | 保存される形 |
|---|---|---|
list | FAQ・経歴・制作の流れ | オブジェクトの配列 |
object-form | 担当者情報・会社概要 | 1つのオブジェクト |
grid | 対応ブラウザ表・営業日 | 行キー→列キー→値 |
tags | 使用技術・キーワード | 文字列の配列 |
list:ACFのリピーターに一番近い
listは、同じ項目を持つ行を追加・削除・並べ替えできる入力欄です。ACFのリピーターから移るなら、まずこれを使います。
{
"slug": "faq",
"label": "よくある質問",
"type": "json",
"widget": "field-kit:list",
"options": {
"itemLabel": "質問",
"max": 10,
"summary": "{{question}}",
"fields": [
{ "key": "question", "label": "質問", "type": "text", "required": true },
{ "key": "answer", "label": "回答", "type": "textarea", "rows": 4 }
]
}
}summary には折りたたんだ行の見出しを {{キー名}} で書けます。質問文を見出しにしておくと、10件並んでも目当ての行をすぐ開けるのが利点です。min と max で件数を縛ると、上限に達したとき追加ボタン自体が消えます。
object-form:項目が固定のまとまり
object-formは、決まった項目を1つのオブジェクトとして保存する形で、担当者の名前・役職・メールのように、数は増えないけれどまとめて扱いたい項目向きです。
{
"slug": "contact_person",
"label": "担当者",
"type": "json",
"widget": "field-kit:object-form",
"options": {
"fields": [
{ "key": "name", "label": "氏名", "type": "text", "required": true },
{ "key": "role", "label": "役職", "type": "text" },
{ "key": "email", "label": "メール", "type": "text" }
]
}
}listとobject-formの各項目には、text・textarea・number・boolean・select・date・color・urlの8種類が使えます。どの項目にも required と helpText、defaultValue を付けられます。
grid:行×列の表を埋める
gridは、行と列を決めておき、各マスを入力させるウィジェットで、マスの種類はトグル・テキスト・数値・選択から1つ選び、表全体に同じ種類が使われる形です。
{
"slug": "support_matrix",
"label": "動作確認環境",
"type": "json",
"widget": "field-kit:grid",
"options": {
"cell": "toggle",
"rows": [
{ "key": "chrome", "label": "Chrome" },
{ "key": "safari", "label": "Safari" },
{ "key": "edge", "label": "Edge" }
],
"columns": [
{ "key": "pc", "label": "PC" },
{ "key": "sp", "label": "スマホ" }
]
}
}保存されるのは { "chrome": { "pc": true, "sp": true } } のような入れ子のオブジェクトです。マスを選択式にするときは cellOptions で選択肢を必ず渡します。
tags:文字列をチップで並べる
tagsは、Enterかカンマで文字列を確定していくチップ型の入力欄で、重複は自動で無視され、空欄でBackspaceを押すと最後のチップが消えるしくみです。設定例は次の節で、このサイトの実物を見せます。
このサイトの実績ページでは「使用技術」をtagsにしている
実績の使用技術は、tagsに候補を17個持たせて、表記ゆれを入口で止めています。管理画面で入れた値が公開ページでどう出るかまで、実物で追います。
候補から選ばせて、無ければ打ち込める
実際の定義はこれだけです。suggestions に並べた技術名は入力中に候補として出て、allowCustom を true にしているので候補に無い技術も追加できます。
{
"slug": "tech_stack",
"label": "使用技術",
"type": "json",
"widget": "field-kit:tags",
"options": {
"placeholder": "技術を入力して Enter",
"allowCustom": true,
"suggestions": ["HTML5", "CSS3", "Sass / SCSS", "JavaScript", "TypeScript",
"jQuery", "Vue.js", "React", "Three.js", "WebGL", "GSAP", "Swiper",
"WordPress", "PHP", "Shopify", "Astro", "Git"]
}
}
候補を置く理由は表記ゆれです。「TypeScript」と「Typescript」と「TS」が混ざると、あとで技術名ごとに実績を集めたくなったとき、全部を手で直すことになります。候補を出しておくと、入力する人はほとんど候補から選んでくれると感じています。
テーマ側は配列を受け取って並べるだけ
公開ページの実績詳細では、保存された配列をそのままチップとして並べています。受け取る関数は、配列のほかに改行区切りの文字列も読めるようにしました。Field Kitを入れる前に作ったデータが残っていても、表示が崩れないようにするためです。
function toStrings(v: unknown): string[] | undefined {
let arr: unknown[];
if (typeof v === "string") arr = v.split("\n"); // 古い改行区切りの値
else if (Array.isArray(v)) arr = v; // Field Kit の配列
else return undefined;
return arr.map((x) => String(x).trim()).filter((s) => s.length > 0);
}
同じ配列は、実績ページの構造化データ(JSON-LD)の keywords にも流していて、一度入れた使用技術が、画面の表示と検索エンジン向けの情報の両方に使われる形です。
ACFから移るときの対応表
ACFのよく使う機能は、Field KitかEmDash本体のどちらかに置き換えられるので、移行の打ち合わせではまずこの表で「どこに寄せるか」を決めています。
ACFの機能 | EmDashでの置き換え先 | 補足 |
|---|---|---|
リピーター | Field Kit の list | 行の見出しは summary で指定 |
グループ | Field Kit の object-form | 項目の種類は8つ |
チェックボックス | Field Kit の tags | allowCustom を false で候補のみ |
表を組むリピーター | Field Kit の grid | 行と列は定義で固定 |
フレキシブルコンテンツ | 本文のカスタムブロック | Field Kit には無い |
画像・ギャラリー | image 型のフィールド | Field Kit の項目には無い |
フレキシブルコンテンツのように「ブロックを並べて1ページを組む」用途は、Field Kitではなく本文側の仕組みで作ります。やり方はリッチテキストを拡張する4つの方法にまとめました。
Field Kitでできないこと
Field Kitは入力画面を足すプラグインなので、データの持ち方そのものは変えられず、設計の段階で次の4つは別の手段に回しておきます。
最後の点はとくに見落としやすいです。カテゴリのように「この値の記事だけ並べたい」ものは、jsonではなく分類(taxonomy)で持ちます。理由はタグを文字列で持つと一覧ページが作れない話に書きました。
どの項目をどの型にするかの全体の考え方は、クライアントが更新しても崩れないフィールド設計で、このサイトの実績コレクションを例に説明しています。
よくある質問
Field Kitを入れたら既存のjsonフィールドはどうなりますか?
widget を指定した欄だけ入力画面が変わります。指定していないjsonフィールドは、今まで通りJSONを書く欄のままです。既存の値もそのまま読み込まれます。
WordPressのACFのデータは、そのまま移せますか?
値は移せますが、ACFの設定そのものは移りません。移行ツールで入ったデータの形を見てから、受け皿になるフィールドとウィジェットを定義し直します。リピーターは配列、グループはオブジェクトとして受けるのが基本です。
管理画面から項目を足せますか?
Field Kitの設定はフィールド定義の options に書くもので、このサイトでは seed/seed.json で管理しています。入力欄の構成を変えるのは実装側の作業で、クライアントは決まった欄に入力するだけ、という分担にしています。
まとめ
Field Kitは、jsonフィールドをクライアントが触れる入力欄に変えるための道具で、データはただのJSONなので、入れても外しても中身は残ります。
EmDashでの管理画面づくりは、入力欄の作り方ひとつでクライアントの問い合わせの数が変わります。ACFで組んだサイトの移行や、更新しやすいフィールド設計を任せたいときは、お問い合わせからご相談ください。現在の構成を見たうえで、置き換え先から一緒に決めます。
本記事は2026年10月時点の情報です。