
Panduan Sanity CMS: Cara Kami Menerbitkan Konten dalam 10 Bahasa
Kami telah menerbitkan lebih dari 400 konten di 4 situs web dan 10 bahasa melalui Sanity CMS. Berikut adalah hal-hal yang kami pelajari, mulai dari desain skema hingga penerbitan multibahasa yang otomatis.
Sanity CMS adalah platform konten headless yang dibangun di sekitar konten terstruktur, Content Lake waktu nyata, dan editor berbasis React yang dapat disesuaikan bernama Sanity Studio. Platform ini menggunakan GROQ untuk kueri, Portable Text untuk konten kaya, dan schema-as-code untuk pemodelan konten. Panduan ini mencakup pengaturan, desain skema, GROQ, Portable Text, arsitektur multibahasa, dan harga.
Apa Itu Sanity CMS?
Sanity adalah platform konten terstruktur, atau apa yang disebut tim Sanity.io sebagai "sistem operasi konten". Berbeda dengan CMS tradisional yang menyimpan blob HTML dalam database, Sanity menyimpan setiap bagian konten sebagai JSON terstruktur di backend yang dikelola bernama Content Lake. Anda dapat mengkuirinya dengan GROQ atau GraphQL, dan merender konten di frontend apa pun yang Anda inginkan: Next.js, React Native, Svelte, aplikasi seluler, alat CLI, atau apa saja.
Perusahaan yang menggunakannya mencakup berbagai skala. Nike, Figma, Puma, dan Cloudflare menjalankan Sanity dalam skala perusahaan. Startup menggunakannya karena tingkat gratisnya benar-benar dapat digunakan (akan dibahas lebih lanjut tentang harga nanti). Kami menggunakannya karena tidak ada solusi lain yang memberi kami fleksibilitas untuk membangun pipa penerbitan 10 bahasa yang sepenuhnya otomatis.
Arsitektur Content Lake
Content Lake adalah backend yang dikelola oleh Sanity. Anggaplah ini sebagai toko dokumen yang di-hosting yang disinkronkan secara real-time di semua klien yang terhubung. Ketika seorang editor mengubah paragraf di Sanity Studio, editor lain langsung melihatnya, tanpa tombol simpan, tanpa konflik penggabungan, tanpa migrasi database.
Di balik layar, dokumen disimpan sebagai JSON terstruktur dengan bidang bertipe. Setiap mutasi dilacak melalui log transaksi, sehingga Anda mendapatkan riwayat versi lengkap secara default. Sinkronisasi waktu nyata menggunakan arsitektur berbasis listener (dijelaskan dalam dokumen arsitektur GitHub Sanity) yang mendorong perubahan ke semua pelanggan melalui observables RxJS.
Apa yang membuat ini berbeda dari, misalnya, database PostgreSQL dengan API REST? Content Lake menangani pemodelan konten, kontrol akses, caching CDN, transformasi gambar, dan kolaborasi waktu nyata sebagai satu layanan yang dikelola. Anda tidak perlu menjalankan migrasi. Anda tidak perlu mengelola replika. Anda cukup mendefinisikan skema dan mengkuiri konten.
Sanity Studio: Editor yang Dapat Disesuaikan
Sanity Studio adalah aplikasi React open-source yang berfungsi sebagai antarmuka pengeditan Anda. Ini bukan panel admin yang di-hosting, melainkan aplikasi React yang berada dalam basis kode Anda. Anda dapat menyesuaikan setiap aspeknya: komponen input kustom, bidang bersyarat, aksi dokumen, pola pembangun struktur, dan plugin.
Kolaborasi waktu nyata sudah内置 (built-in). Beberapa editor dapat bekerja pada dokumen yang sama secara bersamaan dengan indikator kehadiran dan pembaruan langsung. Jika Anda pernah menggunakan Google Docs, pengalamannya serupa; Anda melihat kursor dan perubahan orang lain secara real-time.
Kami men-deploy Studio kami dengan npx sanity deploy, yang menghostingnya di CDN Sanity pada subdomain kustom. Anda juga dapat menghostingnya sendiri karena ini hanyalah aplikasi React. Kami memberikan peringkat tinggi pada Sanity dalam perbandingan headless CMS kami sebagian besar karena fleksibilitas Studio.
Cara Mengatur Proyek Sanity
Untuk mengatur Sanity CMS, instal CLI dengan npm create sanity@latest, pilih templat proyek, konfigurasikan file skema Anda, dan jalankan npx sanity dev untuk meluncurkan Studio secara lokal. Seluruh proses memakan waktu kurang dari 5 menit.
Prasyarat dan Instalasi
Anda memerlukan Node.js 18+ dan npm (atau pnpm). Itu saja. Jalankan perintah init:
npm create sanity@latest
# You'll be prompted for:
# - Login method (Google, GitHub, email)
# - Project name
# - Dataset name (default: "production")
# - Project template (blog, ecommerce, clean)
# - TypeScript? (recommended: yes)CLI akan membuat kerangka proyek dengan semua yang Anda butuhkan. Berikut adalah tampilan struktur proyeknya:
Penjelasan Struktur Proyek
my-sanity-project/
├── schemas/ # Your content schemas (this is where you'll spend time)
│ ├── index.ts # Schema registry -- imports and exports all types
│ ├── post.ts # Document type definitions
│ └── blockContent.ts # Rich text / Portable Text config
├── sanity.config.ts # Main config -- plugins, Studio structure, dataset
├── sanity.cli.ts # CLI config -- project ID, dataset
├── package.json
└── tsconfig.jsonFile sanity.config.ts adalah titik masuk Anda. Berikut adalah contoh minimalnya:
// sanity.config.ts
import { defineConfig } from 'sanity'
import { structureTool } from 'sanity/structure'
import { visionTool } from '@sanity/vision'
import { schemaTypes } from './schemas'
export default defineConfig({
name: 'default',
title: 'My Blog',
projectId: 'your-project-id',
dataset: 'production',
plugins: [structureTool(), visionTool()],
schema: { types: schemaTypes },
})Plugin visionTool() memberi Anda area bermain GROQ di dalam Studio, yang akan sering Anda gunakan selama pengembangan.
Men-deploy Studio Anda
Luncurkan secara lokal dengan npx sanity dev (berjalan di localhost:3333). Ketika Anda siap untuk berbagi dengan editor, deploy ke CDN Sanity:
npx sanity deploy
# Prompts for a hostname, e.g., "my-blog"
# Deploys to https://my-blog.sanity.studioTips pro: jalankan npx sanity@latest schema deploy setelah setiap perubahan skema. Ini mengunggah skema Anda ke API Sanity, yang mengaktifkan fitur seperti API GraphQL dan alat yang sadar skema (termasuk server MCP yang akan kita bahas nanti).
Desain Skema di Sanity CMS
Skema Sanity didefinisikan sebagai objek JavaScript atau TypeScript dalam basis kode Anda. Setiap skema menentukan jenis dokumen dengan bidang, aturan validasi, dan komponen input kustom. Perubahan pada skema bersifat instan, tidak diperlukan migrasi database. Ini adalah pendekatan "schema-as-code", dan inilah hal yang membuat kami memilih Sanity daripada Contentful.
Jenis Bidang dan Validasi
Sanity dilengkapi dengan serangkaian jenis bidang yang kaya. Berikut adalah yang paling sering kami gunakan:
| Jenis Bidang | Kasus Penggunaan | Contoh |
|---|---|---|
string | Teks pendek, judul, slug | Judul postingan, nama penulis |
text | Teks biasa multi-baris | Kutipan, deskripsi |
number | Bilangan bulat, desimal | Waktu baca, urutan sortir |
boolean | Sakelar | Flag unggulan, status draf |
array | Daftar, teks kaya (Portable Text) | Isi konten, tag |
reference | Tautan ke dokumen lain | Penulis, kategori |
image | Gambar dengan metadata | Gambar sampul dengan teks alt |
slug | String ramah URL | Dibuat otomatis dari judul |
object | Grup bidang bersarang | Bidang SEO (metaTitle + metaDescription) |
date / datetime | Tanggal | Tanggal diterbitkan |
Setiap bidang mendukung validasi melalui callback validation. Anda dapat menerapkan bidang wajib, nilai min/maks, pola regex, dan aturan kustom:
defineField({
name: 'seoDescription',
title: 'Meta Description',
type: 'string',
validation: (Rule) =>
Rule.required()
.min(145)
.max(160)
.warning('Meta description should be 145-160 characters'),
})Jenis Blok Kustom (Contoh Produksi Kami)
Di sinilah Sanity menjadi menarik, dan di mana 0 dari 6 panduan pesaing menunjukkan kode apa pun. Dalam skema produksi kami, kami mendefinisikan lima jenis blok kustom di dalam array body: block (teks standar), table, codeBlock, chartBlock, dan inlineImage.
Berikut adalah definisi codeBlock kami:
// schemas/objects/codeBlock.ts
import { defineType } from 'sanity'
export const codeBlock = defineType({
name: 'codeBlock',
title: 'Code Block',
type: 'object',
fields: [
{
name: 'language',
title: 'Language',
type: 'string',
options: {
list: [
{ title: 'JavaScript', value: 'javascript' },
{ title: 'TypeScript', value: 'typescript' },
{ title: 'Python', value: 'python' },
{ title: 'Bash', value: 'bash' },
{ title: 'JSON', value: 'json' },
{ title: 'GROQ', value: 'groq' },
],
},
},
{
name: 'code',
title: 'Code',
type: 'text',
},
],
})Dan berikut adalah cara bidang body mereferensikan semua jenis kustom kami bersama-sama:
// schemas/fields/body.ts
defineField({
name: 'body',
title: 'Body',
type: 'array',
of: [
{ type: 'block' }, // Standard Portable Text (paragraphs, headings, lists)
{ type: 'table' }, // @sanity/table plugin
{ type: 'codeBlock' }, // Our custom code block
{ type: 'chartBlock' }, // Data visualization (bar, line, pie)
{ type: 'inlineImage' }, // Images with alt text and captions
],
})Ini memberi editor kami toolkit konten yang kaya sambil menjaga setiap elemen tetap bertipe dan dapat dikueri. Sebuah chartBlock bukan sekadar embed HTML yang buram, melainkan data terstruktur dengan bidang chartType, title, dataPoints, dan dataLabels. Hal ini penting ketika Anda mencoba merender konten yang sama di web, email, dan seluler.
Praktik Terbaik Organisasi Skema
Jaga agar skema tetap modular. Kami membaginya berdasarkan tipe dalam file terpisah: schemas/documents/post.ts, schemas/objects/codeBlock.ts, schemas/objects/chartBlock.ts. Impor semuanya di schemas/index.ts:
// schemas/index.ts
import { post } from './documents/post'
import { codeBlock } from './objects/codeBlock'
import { chartBlock } from './objects/chartBlock'
import { inlineImage } from './objects/inlineImage'
export const schemaTypes = [post, codeBlock, chartBlock, inlineImage]Wawasan kunci yang kami dapatkan dari bekerja dengan konten terstruktur: skema Anda ADALAH model konten Anda. Jika Anda memikirkannya sebagai rekayasa konteks untuk tim konten Anda, Anda akan membuat keputusan desain yang lebih baik. Setiap bidang yang Anda tambahkan harus memiliki tujuan, baik untuk editor, untuk perenderan, atau untuk pengkuerian.
GROQ: Bahasa Kueri Sanity
GROQ (Graph-Relational Object Queries) adalah bahasa kueri open-source milik Sanity untuk memfilter, menggabungkan, dan memproyeksikan dokumen JSON. Sintaks dasarnya adalah *[filter]{projection}, pilih semua dokumen yang cocok dengan filter, lalu bentuk outputnya. Ini lebih ringkas daripada GraphQL untuk kueri khusus Sanity dan, menurut pengalaman kami, lebih cepat dipelajari.
Kueri Dasar: Filter dan Proyeksi
Kueri paling sederhana mengambil semua dokumen dari suatu tipe:
// Fetch all posts -- just title and slug
*[_type == "post"]{
title,
"slug": slug.current
}
// Filter by language, expand author reference
*[_type == "post" && language == "en"]{
title,
"slug": slug.current,
"authorName": author->name,
"authorImage": author->image,
"categoryTitle": category->title,
publishedAt
}Operator -> mengikuti referensi. author->name berarti "ikuti referensi penulis dan kembalikan bidang nama." Tidak ada kueri terpisah, tidak ada masalah N+1, tidak ada JOIN, semuanya dalam satu ekspresi.
Penggabungan, Pengurutan, dan Paginasi
Untuk halaman indeks blog kami, kami memerlukan postingan yang diurutkan dan dipaginasi dengan referensi yang diperluas:
// Paginated posts with full metadata
*[_type == "post" && language == "en"] | order(publishedAt desc) [0...10] {
title,
"slug": slug.current,
excerpt,
publishedAt,
readTime,
"author": author->{name, image},
"category": category->{title, "slug": slug.current},
"coverImage": coverImage{
"src": asset->url,
alt
}
}[0...10] memberi Anda 10 hasil pertama (indeks 0, akhir eksklusif). | order(publishedAt desc) mengurutkan dari yang terbaru. Proyeksi membentuk output untuk menyertakan tepat apa yang dibutuhkan frontend Anda, tidak lebih.
Anda dapat menguji semua kueri ini secara interaktif menggunakan plugin Vision di dalam Sanity Studio. Ini sangat berharga selama pengembangan. Untuk pola lainnya, lihat cheat sheet GROQ.
GROQ vs GraphQL
Sanity mendukung kedua GROQ dan GraphQL. Kapan Anda harus menggunakan yang mana?
GROQ adalah bahasa asli Sanity. Ini menangani join, proyeksi, dan bidang komputasi dalam satu string kueri. Ini adalah apa yang dioptimalkan oleh Content Lake.
GraphQL tersedia setelah Anda men-deploy skema Anda (npx sanity@latest schema deploy). Gunakan ini ketika Anda membutuhkan alat standar, misalnya, jika frontend Anda sudah menggunakan Apollo Client atau jika tim Anda mengetahui GraphQL tetapi tidak GROQ.
Kami menggunakan GROQ secara eksklusif. Ini lebih ekspresif untuk data Sanity, dan plugin Vision membuat debugging kueri menjadi sepele.
Portable Text: Konten Kaya yang Dilakukan dengan Benar
Portable Text adalah spesifikasi Sanity untuk teks kaya terstruktur. Alih-alih menyimpan konten sebagai string HTML, ia menyimpan array blok bertipe, paragraf, judul, gambar, cuplikan kode, tabel, masing-masing sebagai objek JSON. Ini membuat konten dapat dirender di framework apa pun, platform apa pun, format apa pun.
Struktur Data
Berikut adalah tampilan paragraf dan blok kode sebagai JSON Portable Text:
[
{
"_type": "block",
"_key": "a1b2c3",
"style": "normal",
"markDefs": [],
"children": [
{
"_type": "span",
"_key": "d4e5f6",
"text": "Here's an example of our pipeline config:",
"marks": []
}
]
},
{
"_type": "codeBlock",
"_key": "g7h8i9",
"language": "typescript",
"code": "export default defineConfig({ ... })"
}
]Setiap blok memiliki _type dan _key. Blok teks standar menggunakan "block" dengan children spans (yang mendukung tanda seperti tebal, miring, dan tautan). Blok kustom, seperti codeBlock, chartBlock, table, dan inlineImage kami, menggunakan _type mereka sendiri dan membawa bidang terstruktur.
Mengapa ini penting? Karena HTML adalah format perenderan, bukan format penyimpanan. Jika Anda menyimpan <h2>Judul</h2><p>Beberapa <strong>teks</strong></p> di database Anda, Anda telah mengunci diri Anda ke perenderan web. Anda tidak dapat mengekstraknya dengan bersih untuk aplikasi seluler, buletin email, PDF, atau jendela konteks agen AI. Portable Text memisahkan konten dari presentasi. Spesifikasi Portable Text adalah open source, ini bukan kunci vendor Sanity.
Blok Kustom dalam Produksi
Pipa kerja kami mengonversi Markdown ke Portable Text menggunakan skrip Python (scripts/md_to_portable_text.py). Konverter menangani blok standar, ditambah empat jenis kustom kami:
table, menggunakan skema plugin@sanity/table. Baris dan sel disimpan sebagai data terstruktur.codeBlock, bahasa dan kode sebagai bidang terpisah, memungkinkan penyorotan sintaks saat dirender.chartBlock, jenis grafik, judul, label sumbu, nama seri, dan titik data sebagai JSON terstruktur. Frontend merender ini dengan Chart.js.inlineImage, teks alt, sumber, dan keterangan opsional sebagai bidang terpisah.
Struktur ini berarti kami dapat mengkuiri semua contoh kode di blog kami (*[body[]._type == "codeBlock"]), menemukan postingan dengan grafik, atau mengekstrak semua gambar dengan teks alt yang hilang, semuanya melalui GROQ.
Merender Portable Text
Di frontend, gunakan @portabletext/react (atau ekuivalen Svelte/Vue). Anda mendaftarkan komponen kustom untuk setiap jenis blok:
import { PortableText } from '@portabletext/react'
const components = {
types: {
codeBlock: ({ value }) => (
<pre className={`language-${value.language}`}>
<code>{value.code}</code>
</pre>
),
chartBlock: ({ value }) => <Chart data={value} />,
inlineImage: ({ value }) => (
<figure>
<img src={value.src} alt={value.alt} />
{value.caption && <figcaption>{value.caption}</figcaption>}
</figure>
),
},
}
// In your component:
<PortableText value={post.body} components={components} />Itulah seluruh pipa perenderan. Komponen PortableText menangani blok standar (paragraf, judul, daftar, tanda) secara otomatis. Anda hanya perlu mendefinisikan komponen kustom untuk jenis kustom Anda.
Konten Multibahasa dengan Sanity CMS
Sanity mendukung konten multibahasa melalui lokalisasi tingkat dokumen (dokumen terpisah per bahasa yang dihubungkan oleh referensi kanonik) atau lokalisasi tingkat bidang (bidang yang diterjemahkan dalam satu dokumen). Tingkat dokumen bekerja lebih baik untuk SEO dan penerbitan skala besar, itulah yang kami gunakan di seluruh pipa kerja 10 bahasa kami.
Lokalisasi Tingkat Dokumen vs Tingkat Bidang
| Aspek | Tingkat Dokumen | Tingkat Bidang |
|---|---|---|
| Pendekatan | Dokumen terpisah per bahasa | Semua terjemahan dalam satu dokumen |
| SEO | Setiap dokumen memiliki URL/slug sendiri | URL tunggal, lebih sulit menyajikan halaman per bahasa |
| Kompleksitas kueri | Filter sederhana: language == "de" | Akses bidang bersarang: title.de |
| Ukuran konten | Dokumen kecil dan fokus | Satu dokumen besar dengan semua bahasa |
| Terbaik untuk | Postingan blog, halaman, konten berbasis SEO | String UI kecil, label, metadata |
| Putusan kami | Kami menggunakan ini untuk semuanya | Hanya untuk string UI bersama |
Kami memilih lokalisasi tingkat dokumen karena setiap terjemahan mendapatkan slug sendiri, URL sendiri, dan metadata sendiri. Versi Turki dari postingan tentang Supabase vs Firebase mendapatkan slug supabase-firebase-karsilastirma, bahasa Turki yang benar, bukan hack parameter URL.
Arsitektur Pipa Kerja 10 Bahasa Kami
Begini cara pipa kerja otomatis kami bekerja: kami menulis postingan dalam bahasa Inggris, kemudian menerjemahkannya ke 9 bahasa tambahan (Jerman, Prancis, Belanda, Spanyol, Turki, Italia, Swedia, Norwegia, Arab). Setiap terjemahan melewati konversi Markdown, generasi Portable Text, dan penerbitan API Sanity.
Arsitekturnya terlihat seperti ini:
- Menulis, Markdown Inggris dengan frontmatter YAML
- Menerjemahkan, terjemahan AI ke 9 bahasa (diverifikasi untuk kelengkapan dan diakritik)
- Mengonversi, skrip Python mengonversi setiap file
.mdke JSON Portable Text - Menerbitkan, panggilan API ke Sanity: buat dokumen, unggah gambar, patch referensi
Setiap dokumen memiliki bidang language dan referensi canonicalPost yang menunjuk ke aslinya dalam bahasa Inggris. Berikut adalah kueri GROQ untuk mengambil postingan dan semua terjemahannya:
// Fetch a post and all its translations
*[_type == "post" && slug.current == "sanity-cms-guide" && language == "en"][0]{
title,
language,
"translations": *[
_type == "post" &&
canonicalPost._ref == ^._id
]{
title,
language,
"slug": slug.current
}
}Sisi skemanya cukup mudah, bidang language dengan enum bahasa yang didukung:
defineField({
name: 'language',
title: 'Language',
type: 'string',
options: {
list: [
{ title: 'English', value: 'en' },
{ title: 'German', value: 'de' },
{ title: 'French', value: 'fr' },
{ title: 'Dutch', value: 'nl' },
{ title: 'Spanish', value: 'es' },
{ title: 'Turkish', value: 'tr' },
{ title: 'Italian', value: 'it' },
{ title: 'Swedish', value: 'sv' },
{ title: 'Norwegian', value: 'no' },
{ title: 'Arabic', value: 'ar' },
],
},
validation: (Rule) => Rule.required(),
})Satu jebakan yang kami pelajari dengan susah payah: terbitkan dokumen bahasa Inggris terlebih dahulu, kemudian patch referensi canonicalPost pada terjemahan menggunakan ID dokumen yang diterbitkan, bukan awalan drafts.. Sanity memperlakukan dokumen draf dan yang diterbitkan sebagai entitas terpisah secara internal.
Untuk detail lebih lanjut tentang bagaimana pipa kerja ini terhubung ke Model Context Protocol, lihat bagian berikutnya.
Fitur AI Sanity: MCP, Canvas, dan Konteks Agen
Sanity memposisikan dirinya sebagai sistem operasi konten untuk era AI. Fitur AI utama meliputi server MCP bagi agen AI untuk membaca dan menulis konten, Canvas untuk pengeditan berbantuan AI di dalam Studio, dan Agent Context bagi agen AI produksi untuk mengkuiri konten terstruktur dengan kesadaran skema.
Integrasi Server MCP
Server MCP Sanity memungkinkan agen AI, Claude Code, Cursor, Windsurf, dan lainnya, berinteraksi dengan ruang kerja Sanity Anda secara terprogram. Agen dapat membaca skema, mengeksekusi kueri GROQ, membuat dokumen, dan mengelola konten tanpa wrapper API kustom.
Kami menggunakan server MCP Sanity setiap hari dalam pipa kerja konten kami. Agen AI kami mengkuiri skema untuk memahami struktur dokumen, mengambil postingan yang ada untuk menemukan peluang tautan internal, dan menerbitkan dokumen baru. Protokol MCP memberi agen kesadaran skema, mereka tahu bidang apa yang ada, tipe apa yang diharapkan, dan aturan validasi apa yang berlaku. Jika Anda membangun alur kerja agen AI untuk bisnis, ini adalah pola yang kuat.
Konteks Agen untuk AI Produksi
Agent Context adalah fitur terpisah untuk integrasi AI tingkat produksi. Berbeda dengan server MCP (yang dirancang untuk alat pengembang), Agent Context menyediakan akses baca-saja yang tercakup untuk agen AI yang perlu mengkuiri konten Anda saat runtime, pikirkan chatbot, mesin rekomendasi, atau sistem personalisasi konten.
Perbedaannya penting: MCP adalah untuk alur kerja waktu pembangunan dan editorial (alat pengembangan yang sadar skema), sedangkan Agent Context adalah untuk akses konten runtime dengan autentikasi dan pembatasan laju yang tepat.
Konten terstruktur Sanity memberikannya keunggulan nyata di sini. Situs WordPress menyimpan konten sebagai blob HTML, agen AI harus mengurai HTML untuk memahami konten. Sanity menyimpan dokumen JSON bertipe dengan skema yang ditentukan. Agen dapat mengkuiri *[_type == "product" && category == "electronics"]{name, price, features} dan mendapatkan data yang bersih dan terstruktur kembali. Tanpa scraping, tanpa parsing, tanpa menebak.
Bagaimana Kami Menggunakan Sanity di Techsy
Ini bukan bagian hipotetis. Kami menjalankan Sanity CMS di 4 situs web produksi, menerbitkan dalam 10 bahasa dengan pipa kerja otomatis yang kami bangun selama setahun terakhir. Berikut adalah arsitekturnya.
Arsitektur Pipa Kerja Konten Kami
Pipa kerja berjalan dari riset hingga postingan yang diterbitkan di semua 10 bahasa:
- Riset, analisis kata kunci, identifikasi celah kompetitor, pola SERP
- Brief, spesifikasi penulisan terstruktur dengan panduan bagian, jumlah kata, tautan internal
- Menulis, menghasilkan Markdown Inggris dengan frontmatter YAML
- Mengonversi, skrip Python mengubah Markdown ke JSON Portable Text dengan 5 jenis blok kustom kami
- Menerbitkan, panggilan API ke Sanity: dokumen
createOrReplace, unggah gambar ke CDN Sanity, patch referensi penulis/kategori - Menerjemahkan, terjemahan AI ke 9 bahasa, diverifikasi untuk kelengkapan
- Menerbitkan terjemahan, aliran konversi/penerbitan yang sama per bahasa, dengan referensi
canonicalPostdipatch ke aslinya dalam bahasa Inggris
Skema kustom mendukung jenis block, table, codeBlock, chartBlock, dan inlineImage, semuanya didefinisikan sebagai objek skema Sanity produksi dengan aturan validasi. Di antara alat AI untuk startup yang telah kami uji, pipa kerja berbasis Sanity ini telah menjadi yang paling andal untuk konten terstruktur dalam skala besar.
Pelajaran dari 400+ Konten yang Diterbitkan
Beberapa hal yang kami harap seseorang telah memberitahu kami:
Urutan patch referensi penting. Referensi Sanity tidak dapat menunjuk ke dokumen yang belum ada. Terbitkan postingan bahasa Inggris terlebih dahulu, lalu buat terjemahan dengan canonicalPost yang menunjuk ke ID yang diterbitkan dari dokumen bahasa Inggris. Kami beberapa kali merusak ini di awal.
Deployment skema adalah per-workspace. Jika Anda menjalankan beberapa proyek Sanity (kami menjalankan 4), Anda perlu men-deploy skema ke masing-masing secara terpisah: npx sanity@latest schema deploy per konfigurasi proyek.
Tingkat gratis itu nyata. Kami menjalankan dua dari empat situs kami di paket gratis selama berbulan-bulan. 20 pengguna, 500K permintaan API/bulan, 100K permintaan CDN, itu cukup untuk situs produksi nyata, bukan hanya proyek mainan.
Konversi Portable Text adalah hambatan. Markdown ke Portable Text tidak sepele. Daftar bersarang, tabel di dalam blockquote, blok kode dengan karakter khusus, kasus tepi di mana-mana. Kami telah mengiterasi skrip konverter kami selama berbulan-bulan.
Butuh bantuan mengatur Sanity untuk proyek Anda? Kami telah membangun pipa kerja konten multibahasa untuk 4 situs produksi. Dapatkan konsultasi gratis
Rincian Harga Sanity CMS
Sanity menawarkan tiga paket: Free (20 pengguna, 500K permintaan API/bulan), Growth ($15/pengguna/bulan dengan peran lanjutan dan draf terjadwal), dan Enterprise (harga kustom dengan SLA dan fitur kepatuhan). Tingkat gratis adalah yang paling murah hati di pasar headless CMS.
| Fitur | Free | Growth ($15/pengguna/bln) | Enterprise |
|---|---|---|---|
| Pengguna | 20 | 50 | Tak terbatas |
| Permintaan API | 500K/bulan | 2,5Juta/bulan | Kustom |
| Permintaan CDN | 100K/bulan | 500K/bulan | Kustom |
| Peran | Admin saja | Admin, Developer, Editor, Contributor | Peran kustom |
| Kolaborasi | Pengeditan waktu nyata | + Penerbitan terjadwal, draf | + Alur kerja |
| Dukungan | Komunitas | Dedikasi + SLA | |
| Kepatuhan | , | , | SOC 2, HIPAA |
Pada tingkat gratis, kami menjalankan dua situs kami tanpa mencapai batas. Paket Growth seharga $15/pengguna/bulan menambahkan akses berbasis peran (penting setelah kami memiliki editor non-teknis) dan penerbitan terjadwal. Penonton gratis di Growth, yang merupakan sentuhan bagus, Anda tidak dihukum karena memberi pemangku kepentingan akses baca.
Bagaimana ini dibandingkan dengan pesaing?
| Fitur | Sanity Free | Contentful Free | Strapi Cloud Free | Payload Cloud |
|---|---|---|---|---|
| Pengguna | 20 | 1 | 1 | 1 |
| Jenis konten | Tak terbatas | 48 | Tak terbatas | Tak terbatas |
| Panggilan API | 500K/bln | Termasuk | Termasuk | Termasuk |
| Tipe kustom | Ya | Terbatas | Ya | Ya |
| Harga untuk berkembang | $15/pengguna/bln | $300/bln | $29/bln | $50/bln |
Tingkat gratis 20 pengguna Sanity luar biasa. Contentful membatasi Anda pada 1 pengguna di versi gratis dan melonjak ke $300/bulan untuk paket Tim mereka. Jika Anda adalah startup atau tim kecil, paket gratis Sanity memungkinkan Anda menjalankan beban kerja produksi nyata tanpa mengeluarkan biaya apa pun.
Sanity juga menawarkan program startup yang memberi startup yang memenuhi syarat akses Growth gratis selama satu tahun. Layak untuk diterapkan jika Anda memenuhi syarat.
Pertanyaan yang Sering Diajukan
Apa itu Sanity CMS dan bagaimana cara kerjanya?
Sanity CMS adalah platform konten headless yang menyimpan dokumen JSON terstruktur di backend yang dikelola bernama Content Lake. Anda mengedit konten melalui Sanity Studio (aplikasi React yang dapat disesuaikan), mengkuirinya dengan GROQ atau GraphQL, dan merendernya di framework frontend apa pun. Konten disinkronkan secara real-time di semua klien yang terhubung.
Apakah Sanity CMS gratis?
Ya. Tingkat gratis Sanity mencakup 20 pengguna, 500K permintaan API per bulan, dan 100K permintaan CDN, paket gratis paling murah hati di antara platform headless CMS. Paket Growth berharga $15 per pengguna per bulan dan menambahkan akses berbasis peran, penerbitan terjadwal, dan batas yang lebih tinggi. Harga Enterprise adalah kustom.
Apa perbedaan antara Sanity dan Contentful?
Sanity menggunakan schema-as-code (skema hidup di basis kode Anda), GROQ untuk pengkuerian, dan Studio open-source yang sepenuhnya dapat disesuaikan. Contentful menggunakan pemodelan konten berbasis GUI, GraphQL, dan editor yang di-host dengan kustomisasi yang lebih sedikit. Tingkat gratis Sanity mencakup 20 pengguna dibandingkan dengan 1 milik Contentful. Contentful memiliki marketplace plugin yang lebih besar.
Apakah Sanity CMS bagus untuk pemula?
Sanity Studio intuitif untuk editor konten, pengalaman pengeditan tidak memerlukan pengetahuan teknis. Namun, pengaturan skema memerlukan kemahiran JavaScript atau TypeScript. Sanity menyediakan dokumentasi yang sangat baik, templat proyek, dan Slack komunitas dengan dukungan aktif. Mulailah dengan npm create sanity@latest dan templat blog.
Bisakah saya menghosting Sanity sendiri?
Sanity Studio sepenuhnya dapat dihosting sendiri karena ini adalah aplikasi React open-source. Anda dapat men-deploynya ke Vercel, Netlify, atau penyedia hosting statis apa pun. Backend Content Lake adalah layanan yang dikelola, tidak ada opsi self-hosting untuk lapisan data. Ini adalah tradeoff: Anda mendapatkan nol manajemen infrastruktur tetapi tidak ada kontrol data on-premises.
Jenis database apa yang digunakan Sanity?
Content Lake Sanity bukan database SQL atau NoSQL tradisional. Ini adalah toko dokumen yang dikelola yang menyimpan konten sebagai JSON terstruktur dengan lapisan kueri GROQ di atasnya. Anda tidak berinteraksi dengan database yang mendasarinya secara langsung, Anda berinteraksi melalui API Sanity. Dokumen memiliki riwayat versi lengkap dan sinkronisasi waktu nyata bawaan.
Apakah Sanity CMS open source?
Sanity Studio adalah open source di bawah lisensi MIT, Anda dapat mem-fork-nya, menyesuaikannya, dan menghostingnya sendiri. Backend Content Lake adalah SaaS berpemilik. Spesifikasi bahasa kueri GROQ juga open source, diterbitkan di GitHub. Spesifikasi Portable Text juga open source, dikelola di portabletext.org.
Apa itu Portable Text di Sanity?
Portable Text adalah spesifikasi Sanity untuk teks kaya terstruktur. Alih-alih menyimpan konten sebagai string HTML, ia mewakili paragraf, judul, gambar, dan blok kustom sebagai objek JSON bertipe dalam array. Ini membuat konten portabel di berbagai framework dan platform. Anda dapat mendefinisikan jenis blok kustom seperti cuplikan kode, grafik, dan tabel dengan bidang terstruktur mereka sendiri.
Apa itu GROQ dan bagaimana bedanya dengan GraphQL?
GROQ (Graph-Relational Object Queries) adalah bahasa kueri asli Sanity. Sintaksnya, *[filter]{projection}, lebih ringkas daripada GraphQL untuk data Sanity, dengan dukungan bawaan untuk join melalui operator -> dan bidang komputasi. GraphQL juga tersedia untuk tim yang lebih menyukai alat standar atau sudah menggunakan Apollo Client.
Bagaimana Sanity menangani konten multibahasa?
Sanity mendukung lokalisasi tingkat dokumen (dokumen terpisah per bahasa yang dihubungkan oleh referensi kanonik) dan lokalisasi tingkat bidang (bidang yang diterjemahkan dalam satu dokumen). Tingkat dokumen lebih baik untuk SEO karena setiap terjemahan mendapatkan URL dan metadata sendiri. Kami menggunakan lokalisasi tingkat dokumen untuk menerbitkan di 10 bahasa dengan pipa kerja terjemahan dan penerbitan otomatis.