Sanity(サニティ)は、コンテンツを保存するクラウドのデータベース「Content Lake」と、編集画面「Sanity Studio」を組み合わせて使うヘッドレスCMSです。表示はNext.jsやAstroなど別のフロントエンドが担い、データはGROQかGraphQLのAPIで取り出します。本記事は2026年10月19日公開の最新版 sanity 6.20.0 を前提に、始め方とログイン、スキーマとGROQの書き方、画像と本文の表示、料金の上限、AIエージェントからMCPで操作するときの権限、microCMSなど他のCMSとの選び分けを整理します。
まとめ:Sanityは「データはSaaS、編集画面はコード」で作るヘッドレスCMS
- 読み方は「サニティ」。データの保存と配信はSanityのクラウドが担い、編集画面のSanity StudioはMITライセンスのReactアプリとして自分のリポジトリに置きます。
- 最新版は6.20.0(2026年10月19日)。Studio v6からNode.js 22.12以上が必須です。新規作成は
npm create sanity@latest、起動はnpm run devです。 - コンテンツの型はTypeScriptで
defineType/defineFieldを使って書きます。管理画面で型を作るmicroCMSやContentfulとはここが違います。 - Freeプランは0ドルで20席・1万ドキュメントまで。API・API CDN・転送量の月の枠に達すると超過課金ではなく停止し、APIはHTTP 402を返します。Growthは1席月15ドルです。
- データセットは既定で公開です。Freeは公開データセットしか作れず、公開済みドキュメントは認証なしで誰でも読めます。
- 公式のMCPサーバー(
https://mcp.sanity.io)を使うと、Claude CodeやCursorから公開・非公開化・データセット作成まで実行できます。既定のOAuth接続は自分のロールの権限で動くため、本番データを触らせるならロールを絞ったトークンを渡します。
Sanityの仕組み:Content LakeとSanity Studioの2層構成
| 構成要素 | 役割 | 置き場所 |
|---|---|---|
| Content Lake | ドキュメントの保存・検索・配信 | Sanityのクラウド |
| Sanity Studio | 編集画面(Reactアプリ) | 自分のリポジトリ(MIT) |
| API | GROQ・GraphQL・Mutation | api.sanity.io/apicdn.sanity.io |
| フロントエンド | サイトやアプリの表示 | Next.js・Astroなど任意 |
データベースを自分で立てなくてよい点はContentfulに近く、編集画面をコードで組み替えられる点はStrapiやPayloadに近い、というのがSanityの立ち位置です。ヘッドレスCMS全体の比較軸はヘッドレスCMSとは?従来型との違い・料金比較とプレビュー実装で整理しています。
Content Lake:ドキュメントをJSONで保持するクラウドDB
Content Lakeは、スキーマで定義した型のドキュメントをJSONで保存します(1ドキュメントの上限は32MB)。下書きは drafts.、コンテンツリリースの版は versions. の接頭辞付きIDで保存され、公開すると中身が接頭辞なしのIDへコピーされます。
Sanity Studio:スキーマから生成される編集画面
Studioはnpmパッケージの sanity そのもので、入力欄の差し替えやプラグイン追加をコードで行います。複数人の同時編集と、プレビューしながら編集できるPresentationツールはFreeを含む全プランで使えます。自社サーバーやVercelでも動かせますが、sanity deploy なら <名前>.sanity.studio に無料でホスティングされます。
Sanity Studioの始め方:作成・起動・ログイン・デプロイ
必要なのはNode.js 22.12以上とnpm(またはpnpm・yarn・bun)です。Sanityのアカウントは作成コマンドの途中で作れます。
node --version # v22.12以上であること
npm create sanity@latest
cd my-studio # 作成時に指定したフォルダ名
npm run dev # http://localhost:3333 で Studio が開く
npx sanity deploy # <名前>.sanity.studio にビルドして公開
npm create sanity@latest は、ログイン→プロジェクトとデータセットの作成→テンプレート選択→TypeScriptの有無を対話で進めます。既存のNext.jsプロジェクトの中で実行すると、そのプロジェクト内にStudioを組み込みます。@sanity/cli 8.22.1 の初期化にはAIエディター向けのMCP設定も既定で入っており、不要なら --no-mcp で飛ばせます。
| ファイル | 書く内容 |
|---|---|
| sanity.config.ts | projectId・dataset・プラグイン・スキーマ |
| sanity.cli.ts | CLIが使うprojectId・dataset |
| schemaTypes/ | ドキュメント型の定義ファイル |
ログイン手段:Google・GitHub・メールとSSO
StudioとCLIのログインは同じSanityアカウントを使います。アカウントはGoogle・GitHub・メールとパスワードで作れますが、同じメールアドレスでもサインイン方法が違えば別アカウントになります(公式のアカウント管理ガイド)。招待されたプロジェクトが見えないときは、まず別の方法でログインしていないかを確かめます。@sanity/cli 8.22.1 の sanity login --provider が受け付けるIDは google・github・sanity(メールとパスワード)・vercel の4つです。組織のSAMLによるシングルサインオンは料金表ではEnterpriseの機能で、sanity login --sso <組織のスラッグ> で入ります。
- CIからログインする:ブラウザを開けない環境では
echo "$TOKEN" | sanity login --with-tokenでAPIトークンを渡します。 - Studioのログイン方法を絞る:
sanity.config.tsのauth.providersで指定します。v6からは既定の手段に追加ではなく置き換えになったため、Googleだけを書くとGitHubやメールでは入れなくなります。 - メンバーとトークンの管理:
sanity.io/manageのプロジェクト画面で、招待・ロール変更・APIトークンの発行を行います。
スキーマ定義:defineTypeとdefineFieldによる型のコード管理
Sanityでは、記事や著者といった型を管理画面ではなくTypeScriptのファイルで定義します。型定義がGitで差分管理でき、レビューを通してから本番に出せます。次は記事(post)と著者(author)の定義例です。
// schemaTypes/post.ts
import {defineField, defineType} from 'sanity'
export const post = defineType({
name: 'post',
title: '記事',
type: 'document',
fields: [
defineField({
name: 'title',
title: 'タイトル',
type: 'string',
validation: (rule) => rule.required().max(80),
}),
defineField({
name: 'slug',
type: 'slug',
options: {source: 'title', maxLength: 96},
validation: (rule) => rule.required(),
}),
defineField({name: 'author', title: '著者', type: 'reference', to: [{type: 'author'}]}),
defineField({name: 'mainImage', type: 'image', options: {hotspot: true}}),
defineField({name: 'publishedAt', type: 'datetime'}),
defineField({
name: 'body',
title: '本文',
type: 'array',
of: [{type: 'block'}, {type: 'image', options: {hotspot: true}}],
}),
],
})
// schemaTypes/author.ts
import {defineField, defineType} from 'sanity'
export const author = defineType({
name: 'author',
title: '著者',
type: 'document',
fields: [defineField({name: 'name', type: 'string', validation: (rule) => rule.required()})],
})
// schemaTypes/index.ts
import {author} from './author'
import {post} from './post'
export const schemaTypes = [post, author]
この配列を sanity.config.ts の schema: {types: schemaTypes} に渡します。
type: 'reference'は別ドキュメントへの参照で、取得時にGROQの->で展開します。type: 'image'にhotspot: trueを付けると、編集者が注視点とトリミング範囲を指定できます。効き方は後の画像の章で実行結果を示します。- 本文の
type: 'block'の配列は、リッチテキスト形式「Portable Text」のJSONで保存されます。ofにimageを並べると、本文の途中に画像を挿入できます。
この3ファイルを sanity 6.20.0 の環境に置き、tsc --noEmit で型エラー0件、npx sanity schema validate でエラー0・警告0になることを確認しました。なお、validation が働くのはStudioの編集画面の中だけで、APIから直接書き込む処理(Mutation API)には適用されません。外部システムからデータを入れる場合は、投入側でも同じ検証を実装します。
GROQでのデータ取得:フィルター・射影・参照展開の基本
GROQ(Graph-Relational Object Queries)はSanityが開発したクエリ言語で、「どのドキュメントを」「どの形で」返すかを1本の式で書きます。基本形は *[フィルター]{射影} です。
*[_type == "post" && defined(slug.current)] | order(publishedAt desc)[0...10]{
_id,
title,
"slug": slug.current,
"authorName": author->name
}
*はデータセット全体、[...]が絞り込み条件で、[0...10]は先頭10件です(...は終端を含まない範囲)。author->nameの->が参照の展開です。リゾルバーを書かずに、著者の名前を1回の問い合わせで取れます。
groq-jsで実行した結果:下書きが混ざる条件
このクエリを、Sanity公式のGROQ実装 groq-js 2.0.0 で、公開済み記事2件・下書き1件・著者1件のサンプルデータに対して実行しました。
[
{"_id": "post-2", "title": "GROQの基本", "slug": "groq-basics", "authorName": "山田 花子"},
{"_id": "drafts.post-2", "title": "GROQの基本(改稿中)", "slug": "groq-basics", "authorName": "山田 花子"},
{"_id": "post-1", "title": "Sanity入門", "slug": "sanity-intro", "authorName": "山田 花子"}
]
2件目に drafts.post-2 が返っています。groq-jsはデータをそのまま評価するため、後述する perspective の raw と同じ見え方です。フィルターに !(_id in path("drafts.**")) を足すと、返るIDは post-1 と post-2 の2件だけになりました。
@sanity/clientで取得するときのapiVersion・useCdn・perspective
フロントエンドからは公式の @sanity/client(2026年10月時点で8.10.1)を使います。Next.jsなら、これをラップした next-sanity(13.3.4・Next.js 16に対応)が一般的です。
import {createClient} from '@sanity/client'
export const client = createClient({
projectId: 'abc123xy',
dataset: 'production',
apiVersion: '2026-10-01',
useCdn: true,
perspective: 'published',
})
const posts = await client.fetch(
`*[_type == "post"] | order(publishedAt desc)[0...10]{title, "slug": slug.current}`,
)
apiVersion は日付で指定し、その日付時点の挙動に固定されます。APIバージョン2025-02-19から、perspectiveの既定値が raw(下書きと公開版を並べて返す)から published(公開版のみ)に変わりました。古い日付のまま perspective を省略し、下書きを読める権限のトークンで問い合わせると、下書きが本番サイトに混ざる場合があります。プレビュー画面だけは、閲覧権限のあるトークンをサーバー側で持たせ、perspective: 'drafts' と useCdn: false を指定した別のクライアントを使います。ビルド時に全ページを取得する静的サイトでは、CDNを通さないAPIを使うよう公式が勧めています。
公開を契機にNext.jsのキャッシュを再検証するには、sanity.io/manage のAPI設定でGROQ-powered webhooksを作り、GROQのフィルターで対象の型を絞って送ります。Next.js 16とnext-sanityの公式例は、署名を parseBody で検証してから revalidateTag(body._type, 'max') を呼ぶ形です。この呼び出しはキャッシュを古い状態にするだけで、次のアクセスで裏側から作り直されるまでは古い内容が返ります。Webhookの本数はFreeが2本、Growthが4本までです。
GraphQLを選ぶ前に知る3つの制約
GraphQL APIも使えますが、スキーマを変えるたびに sanity graphql deploy での再生成が要り、インラインの type: 'object' は名前付きの型に切り出さないと変換できず、更新系はMutation APIで書きます。公式もGROQを強く勧めているので、新規案件はGROQと型生成の sanity typegen generate を基本にし、既存フロントエンドがGraphQL前提のときだけGraphQLを選びます。
画像とPortable Textを表示する:image-urlとto-htmlの実行結果
公式ライブラリの @sanity/image-url 2.1.1 と @portabletext/to-html 6.0.0 で、画像のURL生成と本文(Portable Text)のHTML化をNode.js 26.5.0で実行しました。手順は次のとおりで、続くコードを render.mjs として保存して実行します。
mkdir pt-demo && cd pt-demo
npm init -y
npm pkg set type=module
npm i @sanity/[email protected] @portabletext/[email protected]
node render.mjs
画像は2000×3000ピクセルで、編集者が上下10%を切り落とし、注視点を上から30%の位置に置いた想定です。
import {createImageUrlBuilder} from '@sanity/image-url'
import {toHTML} from '@portabletext/to-html'
const builder = createImageUrlBuilder({projectId: 'abc123', dataset: 'production'})
const image = {
_type: 'image',
asset: {_ref: 'image-Tb9Ew8CXIwaY6R1kjMvI0uRR-2000x3000-jpg', _type: 'reference'},
crop: {top: 0.1, bottom: 0.1, left: 0, right: 0},
hotspot: {x: 0.5, y: 0.3, width: 0.4, height: 0.4},
}
console.log(builder.image(image).width(600).url())
console.log(builder.image(image).width(600).height(400).auto('format').url())
const body = [
{_type: 'block', _key: 'a1', style: 'normal', markDefs: [], children: [
{_type: 'span', _key: 's1', text: '本文の', marks: []},
{_type: 'span', _key: 's2', text: '強調', marks: ['strong']},
]},
{_type: 'image', _key: 'a2', ...image},
]
console.log(toHTML(body))
console.log(toHTML(body, {components: {types: {
image: ({value}) => `<img src="${builder.image(value).width(800).url()}" alt="">`,
}}}))
https://cdn.sanity.io/images/abc123/production/Tb9Ew8CXIwaY6R1kjMvI0uRR-2000x3000.jpg?rect=0,300,2000,2400&w=600
https://cdn.sanity.io/images/abc123/production/Tb9Ew8CXIwaY6R1kjMvI0uRR-2000x3000.jpg?rect=0,300,2000,1333&w=600&h=400&auto=format
<p>本文の<strong>強調</strong></p><div style="display:none">Unknown block type "image", specify a component for it in the `components.types` option</div>
<p>本文の<strong>強調</strong></p><img src="https://cdn.sanity.io/images/abc123/production/Tb9Ew8CXIwaY6R1kjMvI0uRR-2000x3000.jpg?rect=0,300,2000,2400&w=800" alt="">
結果から分かることは3つです。
- 切り抜きは幅だけでも効く:幅600だけの指定でも
rect=0,300,2000,2400が付き、編集者が切り落とした上下300ピクセルは配信されません。 - 注視点は幅と高さの両方を指定したときに効く:600×400を指定すると縦1333ピクセルの範囲を注視点の周りから切り出します。今回は注視点の上に余白が足りず、切り抜きの上端(300)で止まりました。READMEにも「hotspotとcropを反映するには画像レコードと幅・高さの両方が必要」とあります。
auto('format')を付けると、ブラウザが対応していればWebPやAVIFで返ります。 - 本文中の画像は描画方法を書かないと消える:
components.types.imageを渡さないと、画像の位置にdisplay:noneの警告文がHTMLとして出力され、コンソールにも同じ警告が出ます。本文に画像やコードブロックなど独自の型を入れたら、型の数だけ描画関数を用意します。Reactなら @portabletext/react(8.0.1)のcomponentsで同じ指定をします。
2.x系の @sanity/image-url では、古い記事でよく見る import imageUrlBuilder from '@sanity/image-url' の既定エクスポートは非推奨で、名前付きの createImageUrlBuilder を使います。
Sanityの料金プラン:Free・Growth・Enterpriseの上限と超過時の挙動
基本料金とContent Lakeの利用枠はプロジェクト単位、AIクレジットは組織単位です。2026年10月23日時点の公式の料金ページの内容は次のとおりです。
| 項目 | Free | Growth | Enterprise |
|---|---|---|---|
| 料金 | 0ドル | 1席 月15ドル | 個別見積もり |
| 席数の上限 | 20 | 50 | 個別 |
| ロール数 | 2 | 5 | カスタム |
| データセット | 2(公開のみ) | 2(非公開も可) | 個別 |
| ドキュメント数 | 1万 | 2.5万 | 個別 |
| APIリクエスト/月 | 25万 | 25万 | 個別 |
| API CDNリクエスト/月 | 100万 | 100万 | 個別 |
| アセット保存容量・月間転送量 | 100GB・100GB | 100GB・100GB | 個別 |
| GROQ-powered webhooks | 2本 | 4本 | 個別 |
| AIクレジット/月 | 1,000 | 1,000 | 5,000 |
| 下書きの変更履歴 | 3日 | 90日 | 365日 |
席課金なので編集者10人のGrowthは月150ドルで、閲覧のみのユーザーは無料です。Growthは上限を超えても従量課金(API 2.5万件ごとに1ドル、API CDN 25万件ごとに1ドル、転送量1GBあたり0.30ドル、アセット1GBあたり0.50ドル)で動き続けます。ドキュメント数だけはGrowthでも従量にならず、月299ドルの追加枠でドキュメント5万・API CDN 500万・API 100万・転送量とアセット各500GBまで広げます。データセットの追加は1つ月999ドルです。コメント・タスク・予約公開・AI AssistはGrowth以上の機能です。
Freeプランは上限で止まる:HTTP 402の意味
FreeとGrowthのトライアルは超過課金ができないハードキャップで、API・API CDN・転送量のいずれかが月の枠に達すると、APIへのリクエストがHTTP 402(plan_limit_reached)で失敗します(公式のPlans and payments)。リクエストのたびにSanityから取得するページは表示されなくなります(静的生成済みのページは配信され続けます)。使用量が80%と100%に達すると管理者にメールが届きます。ドキュメント数が上限に達した場合は読み取りは止まらず、新しい下書きを含む新規作成ができなくなります。
アクセス数が読めない公開サイトをFreeで運用するのは避けるべきです。useCdn: true でAPI CDNの100万件枠を使い、静的生成やISRでAPIへの到達回数を減らしたうえで、本番公開の時点でGrowthに上げるのが安全です。
公開データセットで誰が何を読めるか:導入前に確認する権限の範囲
Sanityのデータセットは既定で「公開」です(公式のデータ保護ガイド)。公開データセットでは、公開済みのドキュメントを認証なしで誰でもクエリできます。projectIdとデータセット名はフロントエンドのコードに書かれるため、公開済みの全ドキュメントを誰でも一括取得できる状態です。
| データ | 公開データセット | 非公開データセット |
|---|---|---|
| 公開済みドキュメント | 認証なしで読める | トークンが必要 |
| 下書き(drafts.) | 認証なしでは返らない | トークンが必要 |
| リリース版(versions.) | 認証なしでは返らない | トークンが必要 |
| 画像などのアセット | URLを知れば見られる | URLを知れば見られる |
- Freeでは非公開データセットを作れない:会員限定記事や社内向け情報を1件でも入れる予定があるなら、最初からGrowth以上で設計します。
- アセットは非公開データセットでも非公開にならない:公式ドキュメントに、非公開データセットにアップロードした画像も認証なしで閲覧できると明記されています。機密資料のPDFを置く用途には向きません。
- トークンをブラウザに配らない:非公開データセットを読むトークンをフロントエンドのJavaScriptに埋め込むと、データセット全体を公開したのと同じになります。サーバー側かNext.jsのServer Componentsなど、ブラウザに届かない場所でだけ使います。
AIエージェントからSanityを操作する:MCPサーバーの設定と権限の絞り方
Sanityは現在「Content Operating System for the AI era」を掲げ、Content AgentやAgent ActionsをFreeから使える機能として料金表に載せています。開発者が最初に触るのは、Sanityがホスティングする公式のMCPサーバーです。以前のローカル版(npmの @sanity/mcp-server)は非推奨になり、公式リポジトリはリモート版への移行を案内しています。MCP(Model Context Protocol)の仕組みそのものはMCP(Model Context Protocol)とは?AIと外部ツールをつなぐ標準規格の仕組みで解説しています。
# Studioのフォルダで実行。検出したAIエディターに設定を書き込む
npx sanity@latest mcp configure
# Claude Codeに手で追加する場合(初回利用時にOAuthで認可)
claude mcp add Sanity -t http https://mcp.sanity.io --scope user
sanity mcp configure は、@sanity/cli 8.22.1 のソースでは Claude Code・Cursor・VS Code・Codex CLI・Gemini CLI など13種類のエディターを対象にしており、ログイン中のCLIユーザーの認証を使って設定します。つないだ後は自然文の指示で、クエリ実行・ドキュメントの作成と更新・スキーマの確認ができます。
注意すべきは、使えるツールに読み取り以外が多く含まれる点です。公式ドキュメントのツール一覧には publish_documents(公開)、unpublish_documents(非公開化)、discard_drafts(下書きの破棄)、create_dataset、add_cors_origin、deploy_schema、deploy_studio が並びます。既定のOAuthもCLIが発行するトークンも本人の権限で動くため、管理者がつなげばAIは管理者と同じ範囲で公開・削除・設定変更ができます。
- 本番データセットにつなぐなら権限を絞ったトークンを使う:MCPの設定に
Authorization: Bearer <トークン>ヘッダーを書くとOAuthを使わず、そのトークンのロールで動きます。調べ物だけならViewerのトークンにします。 - Freeでは中間の権限を作れない:Freeで使えるロールはAdministratorとViewerの2つだけです。データセットを分けても、ロールの権限はプロジェクト内の全データセットに及ぶので隔離になりません。Freeで書き込みを試させるなら本番とは別のプロジェクトを作り、そのプロジェクト専用のトークンを渡します。Growth以上なら、下書きは書けても公開はできないContributorのロールが使えます(公式のロール一覧)。
- AIクレジットを使うのは画像の2ツールだけ:公式のMCPドキュメントでは、AIクレジットを消費するのは
generate_imageとtransform_imageで、ほかのツールは通常のAPI呼び出しです。クエリを繰り返させればAPIリクエストの月25万件枠を消費します。
Studio v3からv6までの変化:古い日本語情報の読み替え
Sanityは2022年12月8日に一般提供を発表したStudio v3で設定方式を刷新しており、それ以前(v2)を前提にした日本語記事がまだ残っています。そのまま打つと別の動作になるコマンドがあります。
| 古い情報(v2) | 現行(v3以降) |
|---|---|
| npm install -g @sanity/cli + sanity init | npm create sanity@latest |
| sanity start で開発サーバー | sanity dev(startはpreviewの別名) |
| sanity.json で設定 | sanity.config.ts + sanity.cli.ts |
| createSchema | defineType / defineField |
v2の sanity start は開発サーバーでしたが、現行CLIでは本番ビルドを確認する sanity preview の非推奨の別名です(@sanity/cli 8.22.1 のソースで hiddenAliases: ['start'])。v3以降のメジャー版は主に動作要件の引き上げで、v4(2025年7月15日)でNode.js 20.19以上、v5(2025年12月16日)でReact 19.2.2以上、v6(2026年6月11日)でNode.js 22.12以上が必須になりました(v4以降はnpmの公開日)。
v5からv6では、Node.jsの最低版のほか、開発時のReact Strict Modeが既定ONになり、auth.providers が置き換えになりました。公式はスキーマ・プラグイン・コンテンツAPIは変わらないとしており、Node.js 22.12以上で動き、React Strict Modeで問題なく動作し、auth.providers をカスタマイズしていなければ npm install sanity@^6 の1行で上がります。sanity.cli.ts で独自のVite設定をしている場合はVite 8への移行も確認します(公式の移行ガイド)。
Sanityのメリット・デメリットとmicroCMS・Strapi・Contentfulとの比較
比べる相手は国産SaaSのmicroCMS、OSSのStrapi、海外SaaSのContentfulが多く、違いが大きいのは型をどこで定義するかとCMS基盤を誰が運用するかです。
| 比較軸 | Sanity | microCMS | Strapi | Contentful |
|---|---|---|---|---|
| 提供形態 | SaaS+OSSの編集画面 | SaaS | OSS+Strapi Cloud | SaaS |
| 型の定義(標準) | TypeScriptのコード | 管理画面 | 管理画面またはJSON | 管理画面・API |
| CMS基盤の運用 | Sanity | microCMS | 自前かStrapi Cloud | Contentful |
| 主なAPI | GROQ・GraphQL | REST | REST・GraphQL | REST・GraphQL |
| 編集画面の改造 | Reactで自由 | 拡張フィールド | プラグイン | アプリ枠 |
無料枠の性質も違います。microCMSのHobbyは0円でAPI呼び出しは無制限ですが、メンバー3名・API5個・コンテンツ1万件までで、データ転送量が月20GBを超えるとAPIが止まります。有料のTeamは月4,900円(税抜)からです(microCMSの料金ページ、2026年10月23日時点)。SanityのFreeは20席まで入れられる代わりに、APIリクエスト数に月の上限があります。
Sanityのメリットは、型定義をコードでレビュー・差分管理できること、編集画面を作り込めること、サーバーを持たずに済むことです。デメリットは、フィールド1つの追加にもコード変更とデプロイが要ること、管理画面の日本語化にプラグインが要ること、席課金で編集者の人数に比例して費用が増えることです。
- Sanityが向く:開発者が常にいて型をコードで管理したい、編集画面を作り込みたい、サーバーは持ちたくない場合。
- microCMSが向く:非エンジニアが日本語の管理画面で型を作り、日本語のサポートを受けたい場合。
- Strapiが向く:データを自社インフラに置く必要がある、席課金を避けたい場合。詳しくはStrapiとは?読み方・使い方と料金を参照してください。
- Contentfulが向く:大規模な多言語運用をSaaSに任せたい場合。料金の増え方はContentfulとは?API構成と料金の増え方で解説しています。
Sanityを選ぶべきでないのは、編集者が自分で型を増やしたい組織です。開発者がいない期間に運用が止まります。Next.jsと同じリポジトリでDBまで持ちたいならPayload CMSも候補になります。どのCMSが合うかを要件から決めたい場合は、弊社のWordPressサイト制作・CMS構築でヘッドレス構成を含めてご相談いただけます。
よくある質問
Sanityの読み方と意味は?
「サニティ」と読みます。英単語の sanity は「正気」「健全さ」という意味です。製品としては2017年11月14日に一般公開されたヘッドレスCMSで、公式は現在「Content Operating System」と名乗っています。
Sanityは無料で使えますか?
使えます。Freeプランは0ドルで、20席・1万ドキュメント・月25万APIリクエスト(CDN経由は100万)までです。ただし枠を超えると課金ではなくAPIが止まり、データセットは公開のみです。本番サイトはGrowth(1席月15ドル)を前提に見積もってください。
Sanity Studioの管理画面は日本語化できますか?
できます。言語プラグイン @sanity/locale-ja-jp(2026年10月時点で1.1.40)を入れ、sanity.config.ts の plugins に jaJPLocale() を加えます。このプラグインはSanityの公式リポジトリで公開されていますが、READMEによると保守はコミュニティで、最初の翻訳はAIによるものです。不自然な訳が残ることがあります。フィールド名は、スキーマの title に日本語を書けば日本語で表示されます。
SanityはNext.jsやAstroで使えますか?
使えます。Next.jsには公式の next-sanity、Astroには公式の @sanity/astro(3.5.2)があり、Studioをサイトの中に埋め込む構成も取れます。Astro側の使い方はAstroフレームワークとは?特徴と使い方もあわせて確認してください。
Sanityから他のCMSへデータを移せますか?
移せます。sanity datasets export production backup.tar.gz でデータセット全体をgzip圧縮のtarとして書き出せ、画像などのアセットも既定で含まれます。--no-drafts で公開版だけ、--types post,author で型を絞った書き出しもできます。本文のPortable TextはJSONなので、移行先ではHTMLやMarkdownへの変換処理が要ります。