「間違えて消しました」に備える|ヘッドレスCMSのバックアップと復元は4層で考える
納品後に飛んでくる「記事を消した」「前の版に戻したい」。ヘッドレスCMSの復元は下書き・リビジョン・ゴミ箱・データベースの4層に分かれ、戻せる範囲も期限も層ごとに違います。自サイト53記事の履歴件数、6週間前のゴミ箱、D1 Time Travelの守備範囲まで実測つきで整理しました。

「先週の文章に戻せますか」。納品から数か月たったサイトで、いちばん急ぎで飛んでくるのがこの手の連絡です。記事を消してしまった、直している途中の原稿が公開された、担当者が代わって前の版を見たい。
自分のサイトはEmDash(Astro向けのヘッドレスCMS)をCloudflareで動かしていて、記事は50本を超えました。戻す機能をひととおり触って確かめたところ、復元は1つの機能ではありませんでした。下書き・リビジョン・ゴミ箱・データベースの4層に分かれ、層ごとに戻せる範囲も期限も違います。引き渡し前に「どの層を誰が使うか」を決めておくと、公開後にあわてる時間が減る。

公開済みの記事を編集しても、ライブは変わらない
いちばん上の層が下書きです。一度公開した記事に手を入れて保存しても、サイトに出ている内容は変わりません。編集は下書きとして溜まり、もう一度「公開」を押したときに入れ替わる。
効くのは「まだ直している途中なのに公開されてしまった」タイプの事故。EmDashには公開版と下書きの差分を見る操作と、下書きを捨てて最後の公開版へ戻す操作の両方があります。何が変わったかを確かめてから捨てる、という順で使う。
実装側の準備は、コレクションの supports に drafts を入れるだけ。クライアントが公開前に見た目を確認したいなら preview も足します(認証付きプレビューURLの実装に書きました)。戻せるのは公開前の編集だけなので、公開後は次の層へ降ります。
履歴は「その記事を何回直したか」しか残らない
supports に revisions を入れると、編集画面のサイドバーから過去の版を一覧・プレビュー・復元できます。復元しても履歴は消えず、新しい版として上に積まれる。
期待とズレやすいのが件数です。自分のサイトの全53本について履歴を数えました(2026年8月13日時点)。1件だけの記事が22本で最多、いちばん多い記事でも6件、公開予約のまま触っていない2本は0件。1年近く運用していて、この薄さです。
理由は、履歴が増えるのが更新したときだからでした。記事の公開日時と履歴の作成日時を突き合わせると、公開の操作をした時刻には1件も増えていない(3本で確認)。作って公開しただけの記事には、ほぼ履歴が残らない計算になります。
つまり「1年分の履歴がある」ではなく「クライアントがそのページを何回直したか」。めったに触らない会社概要は、何年たってもゼロに近いままです。そして supports に revisions を入れ忘れると履歴は最初からゼロで、あとから足しても過去は生えてきません。スキーマを書く段階で決まる項目です。

削除はゴミ箱行きだった。6週間前の記事がまだ戻せる
ここはドキュメントの記述が割れています。編集ガイドは「削除した内容は完全に削除され、復元できない」。CLIとMCPのリファレンスは「ソフト削除でゴミ箱へ移動、restoreで戻せる」。
そこで自分のサイトのゴミ箱を一覧してみたら、2026年7月1日に消したテスト記事が削除日時つきで残っていました。確認したのは8月13日で、6週間前のものがまだ戻せる状態。記事の一覧APIには出てこないので、サイトにも管理画面の一覧にも姿はありません。
API経由の削除はゴミ箱行き、と考えてよさそうです。管理画面の削除ボタンの挙動までは検証していないので、案件で頼りにする前に一度お試しを。ゴミ箱が自動で空になる期限は、ドキュメントに見つけられませんでした。
逆に言えば、消したはずのものが残っている状態でもある。テストで入れた個人情報を本当に消すなら、完全削除まで踏みます。
サイト全体の復旧はTime Travelが本命。バックアップJSONに戻す口はない
CloudflareのD1で動かしているなら、データベースの巻き戻しが常時オンです。設定は不要で、Workers有料プランなら30日前まで、無料プランなら7日前までさかのぼれる。危ない作業の前に現在地のブックマークを控えておき、必要ならその時点へ戻します。
npx wrangler d1 time-travel info <database-name>ただし復元はデータベースをその場で上書きする破壊的な操作。記事もユーザーも設定もまとめて戻るので、「1記事だけ直したい」場面では使いません。
EmDash側にもバックアップがあります。管理画面から1クリックでJSONをダウンロード、R2などのストレージを繋いでいれば日次で自動取得(保持世代は1〜30から選ぶ。予約公開と同じスケジュール実行に乗るため、Cloudflareではcronトリガーが要ります)。中身は記事・下書き・ゴミ箱の項目・スキーマ・メニュー・リビジョン・メディアのメタデータまで。入らないのはユーザーアカウントとAPIトークン、それにメディアの実ファイルです。
正直に押さえておきたいのはここ。ダウンロードしたJSONを戻すワンクリックは、現時点では用意されていません。ドキュメントにも「本番DBの上書きはボタン1つより摩擦があるべき」という趣旨で明記され、CLIからの復元は今後の予定とされています。復旧の本命はTime Travel、バックアップJSONは期限なしの控え、という住み分けです。
自分の環境ではもうひとつ制約に当たりました。wrangler d1 export でSQLダンプを取ろうとすると cannot export databases with Virtual Tables (fts5) で止まる。サイト内検索のためにFTS5の仮想テーブルを持っているせいです。そこで作業前の手順を「Time Travelのブックマークを控える+テーブルごとにJSONで抜く」に変えました。EmDash本体のアップデート前にこれで控えを取り、作業後に記事・実績・メディアの行数を突き合わせています。

引き渡し前に決めておく3つ
- どの層を誰が使うか。クライアントに渡すのは下書きと履歴まで。ゴミ箱の完全削除とデータベースの巻き戻しは実装側で握る。
- supports に何を入れたか。
draftsとrevisionsはスキーマを書いた時点で決まります。更新しても崩れないフィールド設計と一緒に詰めておきたいところ。 - 危ない作業の前の一手。スキーマ変更、一括インポート、CMS本体のアップデート。この3つの前には必ず控えを取る。
「クライアントに更新を任せたいけれど、壊されたときが不安」という相談をよくいただきます。壊れないように作るのと同じくらい、壊れたときにどこまで戻せるかを先に決めておくほうが効く。ヘッドレスCMSでの構築や運用設計の見直しはお問い合わせからご相談ください。
本記事は2026年8月時点の情報です。