
CMS移行の手順ガイド ― コンテンツも画像も、CSV 1本で引っ越す
平原 典彦 — Tesseraを開発しているエンジニア。ヘッドレスCMSとAI連携に関心があります。
CMSの移行で本当に時間を食うのは、記事を移し替える作業そのものではありません。構造(コンテンツタイプとフィールド)を移行先で作り直すことと、画像を1枚ずつダウンロードしてアップロードし直すことです。この記事では、その2つをできるだけ自動に寄せた上で、Tesseraへ移行する手順を上から順に書きます。読みながらそのまま進められる構成にしています。
移行の流れは4ステップです。
- 棚卸し:何を、いくつ、どう参照し合っているかを書き出す
- 書き出し:いまのCMSからCSVを作る
- 取り込み:参照される側から順にCSVを入れる(画像はURLのまま)
- 確認と公開:下書きで入った内容を確認して公開する
ステップ1:棚卸し(30分)
移行前に、次の4点をメモに書き出します。ここを飛ばすと、取り込みの順番で必ず詰まります。
- コンテンツの種類と件数:記事・お知らせ・著者・カテゴリ・タグなど。件数は概算でよい
- 参照関係:「記事 → 著者」「記事 → カテゴリ」のように、どの種類がどの種類を指しているか。矢印の先を先に取り込む必要があります
- 画像の場所:本文中の画像か、アイキャッチのような専用フィールドか。専用フィールドの画像はURLのまま移せます(後述)
- 本文の形式:HTMLかMarkdownか。TesseraのリッチテキストはMarkdownなので、HTMLなら変換が要ります
ステップ2:いまのCMSからCSVを書き出す
TesseraはCSVインポートに対応しています。CSVにする理由は、ほぼどのCMSからでも作れる形式だからです。書き出しの手段はCMSごとに違います。
- 書き出し機能があるCMS:管理画面のエクスポートをそのまま使います。列の名前は後で読み替えられるので、そのままで構いません
- APIしかないCMS:コンテンツAPIで一覧を取得してCSVにします。この変換はClaude CodeやCursorに「このJSONを、この列順のCSVにして」と頼むのが最短です(数分で終わります)。TesseraのMCPを接続していれば、「Tesseraのインポートに合うCSVにして」と頼むだけで、エージェントが仕様(
get_csv_import_spec)を取得して変換します - WordPress:標準の書き出しはWXR(XML)です。CSVにするには書き出しプラグインを使うか、WXRをAIエージェントにCSVへ変換してもらいます。本文はHTMLなので、あわせてMarkdownへ変換します(
turndownのようなライブラリでも、エージェントに頼んでも構いません) - Newt:2026年11月24日にサービスが終了します。APIから取得したJSONをCSVに整形する経路になります。終了日が近づくと駆け込みで混み合うので、早めに書き出しだけでも済ませておくのを勧めます
CSVの形式で守ることは3つだけです。
- 1行目はヘッダー(列名)
- 文字コードはUTF-8推奨。Shift_JISでも自動判定して読めます
- 複数の値は1つのセルにまとめ、「;」または「|」で区切る(どちらでも可)
仕様の全文はCSVインポート仕様にまとめてあります。
例(記事のCSV):
title,body,author,category,coverImage,publishedAt
"はじめての移行","## 見出し
本文です。",山田 花子,お知らせ,https://old-cms.example.com/uploads/hero.jpg,2026-09-01
ポイントは、参照先はIDではなく名前で書くことと、画像はURLのまま書くことです。
ステップ3:参照される側から順に取り込む
3-1. 新しい種類として作る場合(スキーマの雛形を自動推論)
移行先にまだコンテンツの種類が無いなら、「移行」画面にCSVをアップロードします。Tesseraがヘッダーと値から各列の型を推論し、コンテンツの種類の雛形を作ります。

画像URLの列は、メディア型として提案される。取り込み時にURLから取得して自ワークスペースのアセットに保存する。
- 日付らしい列は日付、true/falseの列は真偽値、少数の値を繰り返す列は選択肢
- 画像・PDF・動画のURLだけの列は、メディア型として提案されます(区切りで複数枚なら複数メディア)
- 参照(他の種類への矢印)だけは自動では選びません。列ごとに「参照」を選び、参照先の種類を指定します
内容を確認して「この内容で作成してインポートする」を押すと、種類の作成と取り込みが1回で終わります。やり直したいときは「元に戻す」で取り消せます。
3-2. 既存の種類に入れる場合
種類がすでにある(先に手で作った、または前回の取り込みで作った)なら、その種類の一覧画面を開き、右上の「…」→「CSVインポート」から入れます。ヘッダーは種類のシステム名(title、body など)に合わせます。サンプルCSVをダウンロードすると、列名と書き方がそのまま分かります。

既存の種類へのCSVインポート。既存のコンテンツは変更されず、常に新規として追加される。
3-3. 画像はURLのままでよい
メディア型の列に旧CMSの画像URLが入っていれば、取り込み時にTesseraがそのURLから画像を取得し、あなたのワークスペースのアセットとして保存して紐づけます。事前にダウンロードしてアップロードし直す必要はありません。これはCSVだけでなく、MCPやGraphQLでコンテンツを作るときも同じです。
- 同じ画像を複数の記事で使っていても、取得は1回だけ
- 対応形式は画像・PDF・動画(1ファイル20MBまで)。SVGは対象外
- 取得できなかった行は「行番号+理由」で報告され、他の行の取り込みは止まりません
注意点が1つあります。本文(Markdown)の中に書かれた画像URLは、そのまま旧CMSを指しています。旧CMSを解約する前に、本文中の画像を移し替えてください。MCPを接続していれば、エージェントに「本文中の画像をTesseraに取り込んでURLを差し替えて」と頼めます(import_asset_from_url)。
3-4. 取り込む順番
参照される側 → 参照する側、の順で入れます。たとえば「著者」「カテゴリ」を先に、「記事」を後に。記事CSVの著者列に書いた名前は、先に入れた著者の名前と突き合わせて自動で紐づきます。
ステップ4:確認して公開する
取り込んだコンテンツは、すべて下書きとして入ります。公開中のサイトに突然出ることはありません。一覧の「下書き」タブで内容を確認し、チェックボックスで選んで「公開する」でまとめて公開します。
確認の観点は3つです。
- 参照が正しく紐づいたか(記事の著者・カテゴリが「-」になっていないか)
- 画像が表示されるか(編集画面の右側のパネル)
- 日付と本文の見た目
詰まりやすいところ
- 文字化け:UTF-8で保存し直すのが確実です。ExcelでCSVを保存するときは「CSV UTF-8」を選びます
- 日付:
2026-09-01のようなISO 8601形式にします。2026/9/1は日付として読めません - 先頭ゼロ:郵便番号や商品コードは数値として推論されると先頭の0が消えます。プレビューで型を「テキスト」に変えてください
- 重複:スラッグのような一意の項目が重複している行はエラーになります。行番号が出るので、CSV側を直して再実行します
- 必須項目の空欄:その行だけスキップされます。他の行には影響しません
移行後にできること
移行が終わると、コンテンツはGraphQLで関連を含めて1リクエストで取れ、Claude CodeやCursorからMCPで直接操作できます。「記事にタグを追加したい」と伝えれば構造の変更案が出てくる、という体験は移行後に試してみてください。