CMS
CMS は、Web サイトのコンテンツ管理をその持ち主に渡すための機能です。クライアントはここで編集し、ページを描画するのは制作したサイトのままです。
ヘッドレス CMS なので、テーマもテンプレートもフロントエンドも持ちません。コンテンツを公開すると、Minion が公開ストレージにただの JSON ファイルを書き出します。制作したサイトはそのファイルを (多くの場合ビルド時に) 読み、好きなように描画します。
この切り分けが設計のすべてです。
- 閲覧者が当社を経由しません。 サイトが読むのは静的ファイルなので、アクセスが増えても料金は変わらず、当社の障害がクライアントのサイトの障害になりません。
- リクエスト数で課金しません。 リクエストが当社に来ないので、そもそも計測する対象がありません。
- いつでも卒業できます。 公開されているものは既にただの JSON ファイルです。書き出し (エクスポート) を使えば、そのファイル群とスキーマと画像が 1 つの ZIP で手に入ります。
CMS は experimental で、既定では無効です。サイドバーに出ていない場合はお問い合わせください。
5 分でサイトに繋ぐ
Section titled “5 分でサイトに繋ぐ”1. サイトを作る。 案件ごとに 1 つ作ります。あとで複製・譲渡・削除する単位になります。
2. コンテンツ型を作る。 コンテンツ型は「扱うコンテンツの種類」です。ブログ記事、お知らせ、スタッフ紹介など。形を選びます。
| 種類 | 用途 | 公開される形 |
|---|---|---|
| リスト | 同じ形のエントリを複数持つもの (記事・お知らせ・商品) | エントリの配列 |
| オブジェクト | 1 件しかないもの (サイト設定・トップページ) | 単体のオブジェクト |
あわせて API ID (posts、news など) を決めます。これが公開される JSON のファイル名になるため、あとから変更できません。
3. フィールドを定義する。 各フィールドは ラベル と API ID を持ちます。ラベルは編集者に見える名前で、いつでも変えられます。API ID は公開 JSON のキーになるため、スキーマを公開したあとは固定されます。スキーマビルダーには、定義したフィールドがどんな JSON になるかのプレビューが出ます。
4. エントリを書いて公開する。 下書きの保存は公開面を一切変えません。公開すると、その版が固定され、ファイルが書き出されます。
5. サイトの公開を開始する。 公開は公開ストレージへの書き出しなので、先にワークスペースへ決済手段を登録していただきます。課金はしません。 誰でも無料で使える匿名の公開ストレージは、構造的にフィッシングやマルウェアの置き場になるための措置です。
6. サイトから読み込む。 「配信」タブに、そのサイトのコンテンツ型ごとの URL がコピーボタン付きで並びます。fetch / Next.js / Astro のコード例もそのまま貼れます。
const res = await fetch('https://…/{siteId}/api/posts.json')const { contents } = await res.json()
配信される JSON の形
Section titled “配信される JSON の形”公開すると、コンテンツ型ごとに 1 ファイル、エントリごとに 1 ファイル、そしてマニフェストが書き出されます。
| ファイル | 内容 |
|---|---|
/api/index.json | サイトのコンテンツ型の一覧 (フロントがどの API があるかを知るため) |
/api/{apiId}.json | リスト型のエントリ一覧、またはオブジェクト型の単体 |
/api/{apiId}/{entryId}.json | 個別エントリ (id で引く) |
/api/{apiId}/{slug}.json | 同じエントリ (slug で引く) |
リスト型のファイルはページング形式のレスポンスです。読み取り API と同じ形なので、同じコードがどちらにも使えます。
{ "contents": [ /* エントリ */ ], "totalCount": 12, "offset": 0, "limit": 12}エントリは共通のシステムキーを持ち、そのあとに定義したフィールドが API ID をキーとして並びます。
{ "id": "…", "slug": "hello-world", "createdAt": "2026-01-01T00:00:00.000Z", "updatedAt": "2026-01-01T00:00:00.000Z", "publishedAt": "2026-01-01T00:00:00.000Z", "sortOrder": 0, "title": "こんにちは", "body": "# こんにちは\n…"}テンプレートを書く前に知っておくと良いことが 2 つあります。
- 並び順は適用済みです。 エントリ一覧の画面と同じ順序 (手動の並び替え → 公開日の新しい順) で出ます。
- 参照は 1 段だけ展開されます。 参照先のエントリはオブジェクトとして入ります。未公開だったり 1 段より深い場合は
nullではなく{ "id": "…" }になるので、ref.idを読むテンプレートが落ちることはありません。
フィールド型
Section titled “フィールド型”| 型 | JSON | 補足 |
|---|---|---|
| テキスト | "…" | 1,000 文字まで |
| テキストエリア | "…" | 20,000 文字まで |
| リッチテキスト | "…" | 実体は Markdown。200,000 文字まで |
| 数値 | 0 | |
| 真偽値 | true | |
| 日付 | "2026-01-01" | |
| 選択肢 | "news" | 内部の値ではなくラベルが出ます |
| 画像 / ファイル | { … } | メディアオブジェクト (下記) |
| コンテンツ参照 | { "id": …, "slug": … } | 他のエントリ。1 段展開 |
| 繰り返し | [ { … } ] | オブジェクトの配列。ネストは 1 段、200 行まで |
| 埋め込み URL | "https://…" | YouTube / Vimeo の URL。動画ホスティングは持ちません |
「複数」を有効にしたフィールドは、同じ形の配列になります。
メディアのフィールドはファイル情報に展開されます。
{ "id": "…", "url": "https://…", "object_key": "…", "filename": "cover.jpg", "mime_type": "image/jpeg", "byte_size": 148213, "width": 1200, "height": 630, "alt": "…", "variants": [{ "width": 800, "format": "webp", "url": "https://…" }]}variants はアップロード時に生成した縮小版です。そのまま使っても、srcset に並べても構いません。
名前を安全に変える
Section titled “名前を安全に変える”フィールドは不変の内部 ID で、選択肢は不変の値で保存されています。つまり:
- ラベルの変更はいつでも安全です。 公開中のサイトは何も変わりません。
- API ID はスキーマを公開したあと変更できません。 フロントが読んでいるキーそのものだからです。
- 選択肢のラベルを変えると公開 JSON が変わります。 公開されるのはラベルのほうなので、コンテンツの編集として扱ってください。
- スキーマを変えても既存のエントリは壊れません。 各エントリは自分が書かれた版のスキーマで解釈されます。削除したフィールドは出力に出なくなるだけです。
下書きをプレビューする
Section titled “下書きをプレビューする”下書きは静的ファイルには一切書き出されません。「編集した瞬間に公開ページが壊れる」ことがないのはこのためです。未公開の内容を表示したいときは、読み取り API を使います。
curl -H "X-CMS-API-KEY: YOUR_READ_KEY" \ "https://minion-agent.com/api/public/cms/{siteId}/posts?draftKey=YOUR_DRAFT_KEY"読み取りキーは「配信 → API キー」で発行します。下書きキーも同じタブにあり、漏れた場合は再発行できます (X-MICROCMS-API-KEY も受け付けるので、microCMS 向けに書いたフロントはこの部分を変えずに済みます)。
「設定」の プレビュー URL に制作したサイトのプレビュー用ページを設定しておくと、編集画面の「プレビュー」から生の JSON ではなくそのページが開きます。
読み取り API のクエリは microCMS 互換のサブセットです。
| パラメータ | 例 | |
|---|---|---|
limit / offset | limit=10&offset=20 | 既定 10、最大 100 |
orders | orders=-publishedAt,title | - で降順 |
fields | fields=id,title | 応答を絞る |
filters | filters=category[equals]news[and]title[contains]告知 | equals / not_equals / contains / begins_with / exists / not_exists を [and] [or] で連結。左から順に評価 |
depth | depth=2 | 参照の展開段数。最大 3 |
q | q=キーワード | エントリ全体への全文検索 |
レート制限はサイトごとに読み取り 300 回 / 分、書き込み 60 回 / 分です。
公開のたびに再ビルドする
Section titled “公開のたびに再ビルドする”静的に生成するサイトでは、コンテンツを公開しただけでは半分です。サイト側の再ビルドが要ります。Webhook はそのためにあります。
まずホスティング側でビルドフックを作り (Vercel は Settings → Git → Deploy Hooks、Netlify は Site configuration → Build & deploy → Build hooks)、その URL を「配信 → Webhook」に貼ります。以降は公開のたびにビルドが走ります。登録したらすぐ テスト を送ってください。届いていない Webhook に気づくなら、来週ではなく今のほうが安上がりです。
購読するイベントは選べます。空のままにすると全イベントを受け取ります。
entry.published · entry.unpublished · entry.deleted · content_type.updated · site.published
ペイロードは JSON で、x-cms-event ヘッダ付きで送られます。
{ "event": "entry.published", "site_id": "…", "content_type": "posts", "entry_id": "…", "entry_slug": "hello-world", "occurred_at": "2026-01-01T00:00:00.000Z"}ペイロードに署名する を有効にすると x-cms-signature ヘッダが付きます。作成時に一度だけ表示されるシークレットで、本文そのものを HMAC-SHA256 したものです。ビルドを叩く以上のことをする受け口なら検証してください。
Webhook の失敗で公開が巻き戻ることはありません。ビルドが落ちても、コンテンツは正しく公開されたままです。ビルドを直して再度発火させてください。
エントリには 公開日時 と 公開終了日時 を設定できます。実行は 5 分間隔なので、「その時刻から 5 分以内」と考えてください。予約公開も手動の公開と同じ検証を通ります。必須項目が空のときは、予約を黙って取り下げずに失敗として報告するので、エントリを直せば次の実行で公開されます。
上限と、超えたときの挙動
Section titled “上限と、超えたときの挙動”サイト数とメディアの容量はワークスペース単位で数えます。
| プラン | サイト数 | メディア容量 |
|---|---|---|
| Free | 2 | 1 GB |
| Starter | 5 | 10 GB |
| Team | 20 | 50 GB |
| Business | 100 | 200 GB |
| Enterprise | 無制限 | 1 TB |
上限を超えて止まるのは新規アップロードだけです。既に公開しているファイルは配信され続け、公開の操作も通ります。容量を理由にクライアントの稼働中のサイトを落とすことはしません。
誰が何をできるか
Section titled “誰が何をできるか”ワークスペースのメンバーは全員サイトを見られます。ただし、許可するまで誰も変更できません。
| 権限 | できること |
|---|---|
| 管理者 | すべて (公開の開始停止・API キー・Webhook・アクセス権・サイトの削除) |
| 編集できる | コンテンツ型とスキーマの変更、および執筆者ができること全部 |
| 執筆できる | エントリとメディア (執筆・公開・アップロード) |
| 閲覧のみ | 読み取り。ワークスペースメンバーの既定 |
管理者は自動で決まります (ワークスペースの owner・admin と、サイトを作った本人)。残りの 2 つは サイトごとに設定 → アクセス権で付与します。付与を外すと、その人は閲覧のみに戻ります。
コンテンツを書く人には執筆できるを、構造を変えてよい人にだけ編集できるを付与してください。 フィールドを削除すると、そのエントリを次に公開した時点で公開 JSON から消えます。執筆担当者が うっかり踏んでよい操作ではありません。
組み込み用の画面を畳む
Section titled “組み込み用の画面を畳む”サイトを繋ぎ終えると、配信タブとスキーマタブは役目を終え、コンテンツを書く人にとっては ノイズになります。設定 → 組み込みモードでこれを畳むと、執筆に必要な画面だけになります。 引き渡す前にオフにし、繋ぎ方を変えるときにまたオンにしてください。
変わるのは表示だけで、誰に何が許されるかは変わりません。サイトを守っているのは上の権限のほうです。 執筆できる・閲覧のみの人には、この設定に関係なくこれらのタブは出ません。
サイトを複製する / 譲渡する
Section titled “サイトを複製する / 譲渡する”複製は、同じコンテンツ型・同じスキーマ・同じ API ID を持つ新しいサイトを作ります (エントリと画像も含めるか選べます)。複製先は必ず非公開で始まり、エントリは下書きになります。API キーと Webhook は意図的に引き継ぎません。破壊的なスキーマ変更を試すときや、前の案件の構成を次の案件で使い回すときに使ってください。
譲渡はサイトを別のワークスペースへ移します。相手のワークスペーススラッグを入力すると、相手の管理者が受け入れた時点で移ります。サイトの公開面の識別子は何も変わりません。メディアの URL も API のパスも API キーも Webhook も、ワークスペースではなくサイトに紐づいているためです。稼働中のサイトを止めずに渡せますし、クライアントの CI の環境変数を書き換える必要もありません。
計画に織り込んでおくとよい点が 2 つあります。サイトごとのアクセス権は破棄されます (旧ワークスペースのメンバーを指していたため)。既定は閲覧のみなので、受け取り側は管理者が自分たちのメンバーに権限を付与するまで、管理者以外は編集できません。そして譲渡先のプラン上限を超えていても譲渡は成立します — 既存のファイルは配信され続け、止まるのは新規アップロードだけです。
すべて書き出す
Section titled “すべて書き出す”書き出しは、下書きを含む全コンテンツ・中立的な形式のスキーマ定義・メディアを 1 つの ZIP にまとめます。
published/ フォルダには、配信していた JSON がそのままの形で入っています。移行の途中でも、このファイル群を任意の静的ホスティングに置けばサイトは動き続けます。
メディアの同梱は 200 MB で打ち切り、超えた分はマニフェストに URL 参照として載せます。打ち切りは README・マニフェスト・レスポンスヘッダに必ず明記され、黙って減らされることはありません。