
دليل Sanity CMS: كيف ننشر بـ 10 لغات
نشرنا أكثر من 400 قطعة محتوى عبر 4 مواقع و10 لغات من خلال Sanity CMS. هذا ما تعلمناه — من تصميم المخطط إلى النشر المتعدد اللغات الآلي.
Sanity CMS منصة محتوى headless مبنية على المحتوى المنظم وContent Lake في الوقت الفعلي ومحرر React قابل للتخصيص يُسمى Sanity Studio. يستخدم GROQ للاستعلام وPortable Text للمحتوى الغني وschema-as-code لنمذجة المحتوى. يغطي هذا الدليل الإعداد وتصميم المخطط وGROQ وPortable Text والبنية متعددة اللغات والتسعير.
ما هو Sanity CMS؟
Sanity منصة محتوى منظم — ما يسميه فريق Sanity.io "نظام تشغيل المحتوى". على خلاف أنظمة إدارة المحتوى التقليدية التي تخزن HTML في قاعدة بيانات، يخزن Sanity كل محتوى كـ JSON منظم في خلفية مُدارة تُسمى Content Lake. تستعلم عنه باستخدام GROQ أو GraphQL، وتعرض المحتوى في أي واجهة أمامية تريدها: Next.js أو React Native أو Svelte أو تطبيق جوال أو أداة CLI — أي شيء.
الشركات التي تستخدمه تتنوع على نطاق واسع. Nike وFigma وPuma وCloudflare تشغّل Sanity على مقياس المؤسسات. تستخدمه الشركات الناشئة لأن الطبقة المجانية قابلة للاستخدام الفعلي (المزيد عن التسعير لاحقاً). نحن نستخدمه لأنه لا يوجد شيء آخر أعطانا المرونة اللازمة لبناء خط نشر آلي بـ 10 لغات.
بنية Content Lake
Content Lake هو الخلفية المُدارة في Sanity. فكّر فيه كمخزن وثائق مستضاف يزامن في الوقت الفعلي عبر جميع العملاء المتصلين. عندما يغيّر محرر فقرة في Sanity Studio، يرى المحرر الآخر التغيير فوراً — بدون زر حفظ، بدون تعارضات، بدون هجرات قاعدة بيانات.
تحت الغطاء، تُخزَّن الوثائق كـ JSON منظم بحقول مكتوبة. كل تعديل يُتتبع عبر سجل معاملات، لذا تحصل على تاريخ كامل للإصدارات بشكل افتراضي. تستخدم المزامنة الفورية بنية قائمة على المستمعين (موثقة في وثائق بنية Sanity على GitHub) تدفع التغييرات لجميع المشتركين عبر RxJS observables.
ما الذي يجعل هذا مختلفاً عن قاعدة بيانات PostgreSQL مع REST API مثلاً؟ يتولى Content Lake نمذجة المحتوى والتحكم في الوصول وتخزين CDN المؤقت وتحويلات الصور والتعاون الفوري كخدمة مُدارة واحدة. لا تشغّل هجرات. لا تدير نسخاً احتياطية. تعرّف المخططات وتستعلم عن المحتوى فقط.
Sanity Studio: محررك القابل للتخصيص
Sanity Studio تطبيق React مفتوح المصدر يعمل كواجهة تحرير. إنه ليس لوحة إدارة مستضافة — بل تطبيق React يعيش في قاعدة الكود الخاصة بك. يمكنك تخصيص كل جانب منه: مكونات input مخصصة وحقول شرطية وإجراءات الوثيقة وأنماط بناء الهيكل والمكونات الإضافية.
التعاون الفوري مدمج. يمكن لعدة محررين العمل على نفس الوثيقة في آن واحد مع مؤشرات الحضور والتحديثات الفورية. إذا استخدمت Google Docs من قبل، فالتجربة مشابهة — ترى مؤشرات الآخرين وتغييراتهم في الوقت الفعلي.
ننشر Studio الخاص بنا باستخدام npx sanity deploy، مما يستضيفه على CDN الخاص بـ Sanity بنطاق فرعي مخصص. يمكنك أيضاً استضافته ذاتياً لأنه مجرد تطبيق React. صنّفنا Sanity بمرتبة عالية في مقارنة headless CMS بسبب مرونة Studio في المقام الأول.
كيفية إعداد مشروع Sanity
لإعداد Sanity CMS، ثبّت CLI باستخدام npm create sanity@latest، واختر قالب مشروع، وهيّئ ملفات المخطط، وشغّل npx sanity dev لتشغيل Studio محلياً. تستغرق العملية بأكملها أقل من 5 دقائق.
المتطلبات الأساسية والتثبيت
تحتاج إلى Node.js 18+ وnpm (أو pnpm). هذا كل شيء. شغّل أمر التهيئة:
npm create sanity@latest
# ستُطلب منك:
# - طريقة تسجيل الدخول (Google أو GitHub أو البريد الإلكتروني)
# - اسم المشروع
# - اسم مجموعة البيانات (الافتراضي: "production")
# - قالب المشروع (blog أو ecommerce أو clean)
# - TypeScript؟ (موصى به: نعم)يُنشئ CLI مشروعاً بكل ما تحتاجه. إليك هيكل المشروع:
شرح هيكل المشروع
my-sanity-project/
├── schemas/ # مخططات المحتوى الخاصة بك (هنا ستقضي معظم وقتك)
│ ├── index.ts # سجل المخطط -- يستورد ويصدر جميع الأنواع
│ ├── post.ts # تعريفات نوع الوثيقة
│ └── blockContent.ts # تهيئة النص الغني / Portable Text
├── sanity.config.ts # التهيئة الرئيسية -- المكونات الإضافية وهيكل Studio ومجموعة البيانات
├── sanity.cli.ts # تهيئة CLI -- معرف المشروع ومجموعة البيانات
├── package.json
└── tsconfig.jsonملف sanity.config.ts هو نقطة الدخول. إليك مثال بسيط:
// 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 },
})المكون الإضافي visionTool() يمنحك ملعب GROQ داخل Studio — ستستخدمه باستمرار أثناء التطوير.
نشر Studio الخاص بك
شغّل محلياً باستخدام npx sanity dev (يعمل على localhost:3333). عندما تكون جاهزاً للمشاركة مع المحررين، انشر على CDN الخاص بـ Sanity:
npx sanity deploy
# يطلب اسم مضيف، مثل "my-blog"
# ينشر على https://my-blog.sanity.studioنصيحة احترافية: شغّل npx sanity@latest schema deploy بعد أي تغيير في المخطط. يرفع هذا مخططك إلى API الخاص بـ Sanity، مما يفعّل ميزات مثل GraphQL API والأدوات المدركة للمخطط (بما في ذلك خادم MCP الذي سنغطيه لاحقاً).
تصميم المخطط في Sanity CMS
تُعرَّف مخططات Sanity كـ JavaScript أو TypeScript في قاعدة الكود. يحدد كل مخطط نوع وثيقة بحقول وقواعد تحقق ومكونات input مخصصة. التغييرات على المخططات فورية — لا هجرات قاعدة بيانات مطلوبة. هذا هو نهج "schema-as-code"، وهو ما جعلنا نختار Sanity على Contentful.
أنواع الحقول والتحقق
يأتي Sanity مع مجموعة غنية من أنواع الحقول. إليك الأكثر استخداماً من قبلنا:
| نوع الحقل | حالة الاستخدام | مثال |
|---|---|---|
string | نص قصير وعناوين وslug | عنوان المنشور واسم المؤلف |
text | نص عادي متعدد الأسطر | مقتطفات وأوصاف |
number | أعداد صحيحة وعشرية | وقت القراءة وترتيب الفرز |
boolean | تبديلات | علامة مميزة وحالة مسودة |
array | قوائم ونص غني (Portable Text) | محتوى الجسم والعلامات |
reference | روابط لوثائق أخرى | المؤلف والفئة |
image | صور مع بيانات وصفية | صورة الغلاف مع النص البديل |
slug | سلاسل URL صديقة | مُنشأة تلقائياً من العنوان |
object | مجموعات حقول متداخلة | حقول SEO (metaTitle + metaDescription) |
date / datetime | تواريخ | تاريخ النشر |
كل حقل يدعم التحقق عبر callback من نوع validation. يمكنك فرض الحقول المطلوبة وقيم min/max وأنماط regex وقواعد مخصصة:
defineField({
name: 'seoDescription',
title: 'Meta Description',
type: 'string',
validation: (Rule) =>
Rule.required()
.min(145)
.max(160)
.warning('Meta description should be 145-160 characters'),
})أنواع الكتل المخصصة (أمثلة من الإنتاج)
هنا يصبح Sanity مثيراً للاهتمام — وحيث لا يُظهر أي من الأدلة المنافسة أي كود. في مخططنا الإنتاجي، نعرّف خمسة أنواع كتل مخصصة داخل مصفوفة body: block (نص قياسي) وtable وcodeBlock وchartBlock وinlineImage.
إليك تعريف codeBlock الخاص بنا:
// 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',
},
],
})وهذا هو كيفية إشارة حقل body لجميع أنواعنا المخصصة معاً:
// schemas/fields/body.ts
defineField({
name: 'body',
title: 'Body',
type: 'array',
of: [
{ type: 'block' }, // Portable Text القياسي (فقرات وعناوين وقوائم)
{ type: 'table' }, // مكون @sanity/table الإضافي
{ type: 'codeBlock' }, // كتلة الكود المخصصة الخاصة بنا
{ type: 'chartBlock' }, // تصور البيانات (bar وline وpie)
{ type: 'inlineImage' }, // صور مع نص بديل وتعليقات
],
})هذا يمنح محررينا مجموعة أدوات محتوى غنية مع إبقاء كل عنصر مكتوباً وقابلاً للاستعلام. chartBlock ليس مجرد تضمين HTML معتم — بل بيانات منظمة بحقول chartType وtitle وdataPoints وdataLabels. هذا مهم عندما تحاول عرض نفس المحتوى عبر الويب والبريد الإلكتروني والجوال.
أفضل ممارسات تنظيم المخطط
أبقِ المخططات معيارية. نقسّم مخططاتنا عبر ملفات حسب النوع: schemas/documents/post.ts وschemas/objects/codeBlock.ts وschemas/objects/chartBlock.ts. استوردها جميعاً في 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]الفكرة الجوهرية التي اكتسبناها من العمل مع المحتوى المنظم: مخططك هو نموذج محتواك. إذا فكرت فيه كـ هندسة السياق لفريق المحتوى لديك، ستتخذ قرارات تصميم أفضل. كل حقل تضيفه يجب أن يخدم غرضاً — إما للمحررين أو للعرض أو للاستعلام.
GROQ: لغة استعلام Sanity
GROQ (Graph-Relational Object Queries) هي لغة استعلام Sanity مفتوحة المصدر لتصفية وربط وإسقاط وثائق JSON. الصيغة الأساسية هي *[filter]{projection} — اختر جميع الوثائق المطابقة للفلتر، ثم شكّل الناتج. أكثر إيجازاً من GraphQL لاستعلامات Sanity المحددة، وأسرع في التعلم من واقع تجربتنا.
استعلامات أساسية: التصفية والإسقاط
أبسط استعلام يجلب جميع وثائق نوع معين:
// جلب جميع المنشورات -- العنوان والslug فقط
*[_type == "post"]{
title,
"slug": slug.current
}
// التصفية حسب اللغة وتوسيع مرجع المؤلف
*[_type == "post" && language == "en"]{
title,
"slug": slug.current,
"authorName": author->name,
"authorImage": author->image,
"categoryTitle": category->title,
publishedAt
}المعامل -> يتبع المراجع. author->name يعني "اتبع مرجع المؤلف وأعد حقل الاسم". لا استعلامات منفصلة، لا مشاكل N+1، لا JOINs — كل شيء في تعبير واحد.
الربط والترتيب والترقيم الصفحي
لصفحات فهرس المدونة الخاصة بنا، نحتاج منشورات مرتبة مع مراجع موسعة:
// منشورات مرقّمة صفحياً مع بيانات وصفية كاملة
*[_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] يعطيك أول 10 نتائج (مفهرسة من 0، نهاية مستثناة). | order(publishedAt desc) يرتب الأحدث أولاً. الإسقاط يشكّل الناتج ليتضمن ما يحتاجه frontend الخاص بك بالضبط — لا أكثر.
يمكنك اختبار كل هذه الاستعلامات تفاعلياً باستخدام مكون Vision الإضافي داخل Sanity Studio. لا يقدر بثمن أثناء التطوير. لمزيد من الأنماط، راجع ورقة الغش GROQ.
GROQ مقابل GraphQL
يدعم Sanity كلاً من GROQ وGraphQL. متى تستخدم أياً منهما؟
GROQ هي اللغة الأصلية لـ Sanity. تتعامل مع الربط والإسقاط والحقول المحسوبة في سلسلة استعلام واحدة. وهو ما تم تحسين Content Lake من أجله.
GraphQL متاح بعد نشر مخططك (npx sanity@latest schema deploy). استخدمه عندما تحتاج إلى أدوات موحدة — على سبيل المثال، إذا كان frontend الخاص بك يستخدم Apollo Client بالفعل، أو إذا كان فريقك يعرف GraphQL لكنه لا يعرف GROQ.
نحن نستخدم GROQ حصرياً. أكثر تعبيراً لبيانات Sanity، والمكون الإضافي Vision يجعل تصحيح الاستعلامات تافهاً.
Portable Text: المحتوى الغني بالطريقة الصحيحة
Portable Text هي مواصفة Sanity للنص الغني المنظم. بدلاً من تخزين المحتوى كسلاسل HTML، تخزّن مصفوفة من الكتل المكتوبة — فقرات وعناوين وصور وأكواد وجداول — كل منها كـ JSON. هذا يجعل المحتوى قابلاً للعرض في أي إطار عمل وأي منصة وأي تنسيق.
هيكل البيانات
إليك كيف تبدو فقرة وكتلة كود كـ Portable Text JSON:
[
{
"_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({ ... })"
}
]كل كتلة لها _type و_key. كتل النص القياسية تستخدم "block" مع spans للأطفال (تدعم marks مثل الغامق والمائل والروابط). الكتل المخصصة — مثل codeBlock وchartBlock وtable وinlineImage — تستخدم _type الخاص بها وتحمل حقولاً منظمة.
لماذا يهم هذا؟ لأن HTML تنسيق عرض وليس تنسيق تخزين. إذا خزنت <h2>Title</h2><p>Some <strong>text</strong></p> في قاعدة بياناتك، فقد ربطت نفسك بالعرض على الويب. لا يمكنك استخراج ذلك بشكل نظيف لتطبيق جوال أو رسالة إخبارية بالبريد الإلكتروني أو PDF أو نافذة سياق وكيل ذكاء اصطناعي. Portable Text يفصل المحتوى عن العرض. مواصفة Portable Text مفتوحة المصدر — إنها ليست قيداً من Sanity.
الكتل المخصصة في الإنتاج
يحوّل خط النشر الخاص بنا Markdown إلى Portable Text باستخدام سكريبت Python (scripts/md_to_portable_text.py). يتعامل المحوّل مع الكتل القياسية، إضافة إلى أنواعنا المخصصة الأربعة:
table— يستخدم مخطط مكون@sanity/tableالإضافي. الصفوف والخلايا مخزنة كبيانات منظمة.codeBlock— اللغة والكود كحقول منفصلة، مما يتيح تمييز الصيغة عند العرض.chartBlock— نوع المخطط والعنوان وتسميات المحاور وأسماء السلاسل ونقاط البيانات كـ JSON منظم. يعرضها frontend باستخدام Chart.js.inlineImage— النص البديل والمصدر والتعليق الاختياري كحقول منفصلة.
هذه البنية تعني أنه يمكننا الاستعلام عن جميع أمثلة الكود في مدونتنا (*[body[]._type == "codeBlock"])، وإيجاد المنشورات التي تحتوي على مخططات، أو استخراج جميع الصور ذات النص البديل المفقود — كل ذلك عبر GROQ.
عرض Portable Text
في frontend، استخدم @portabletext/react (أو ما يعادله لـ Svelte/Vue). تسجّل مكونات مخصصة لكل نوع كتلة:
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>
),
},
}
// في المكوّن الخاص بك:
<PortableText value={post.body} components={components} />هذا هو خط العرض الكامل. يتعامل مكوّن PortableText مع الكتل القياسية (فقرات وعناوين وقوائم وmarks) تلقائياً. تعرّف مكونات مخصصة فقط لأنواعك المخصصة.
المحتوى متعدد اللغات مع Sanity CMS
يدعم Sanity المحتوى متعدد اللغات من خلال التعريب على مستوى الوثيقة (وثائق منفصلة لكل لغة مرتبطة بمرجع canonical) أو التعريب على مستوى الحقل (حقول مترجمة داخل وثيقة واحدة). التعريب على مستوى الوثيقة أفضل لـ SEO والنشر على نطاق واسع — هذا ما نستخدمه عبر خط النشر الخاص بنا بـ 10 لغات.
التعريب على مستوى الوثيقة مقابل مستوى الحقل
| الجانب | مستوى الوثيقة | مستوى الحقل |
|---|---|---|
| النهج | وثيقة منفصلة لكل لغة | جميع الترجمات في وثيقة واحدة |
| SEO | لكل وثيقة URL/slug خاص بها | URL واحد، أصعب لخدمة صفحات لكل لغة |
| تعقيد الاستعلام | فلاتر بسيطة: language == "de" | الوصول للحقل المتداخل: title.de |
| حجم المحتوى | وثائق صغيرة ومركّزة | وثيقة واحدة كبيرة بجميع اللغات |
| الأفضل لـ | مقالات المدونة والصفحات والمحتوى المدفوع بـ SEO | سلاسل UI صغيرة وتسميات وبيانات وصفية |
| حكمنا | نستخدم هذا لكل شيء | فقط لسلاسل UI المشتركة |
اخترنا التعريب على مستوى الوثيقة لأن كل ترجمة تحصل على slug خاص بها وURL خاص بها وبيانات وصفية خاصة بها. النسخة التركية من منشور حول Supabase مقابل Firebase تحصل على slug supabase-firebase-karsilastirma — تركية أصيلة، وليست حيلة URL parameter.
بنية خط النشر الخاص بنا بـ 10 لغات
إليك كيف يعمل خط النشر الآلي الخاص بنا: نكتب منشوراً بالإنجليزية، ثم نترجمه إلى 9 لغات إضافية (الألمانية والفرنسية والهولندية والإسبانية والتركية والإيطالية والسويدية والنرويجية والعربية). تمر كل ترجمة عبر تحويل Markdown وتوليد Portable Text ونشر Sanity API.
تبدو البنية هكذا:
- الكتابة — Markdown بالإنجليزية مع YAML frontmatter
- الترجمة — ترجمة بالذكاء الاصطناعي إلى 9 لغات (مع التحقق من الاكتمال والحروف الصحيحة)
- التحويل — سكريبت Python يحوّل كل ملف
.mdإلى Portable Text JSON - النشر — استدعاءات API إلى Sanity: إنشاء وثيقة ورفع صور وترقيع مراجع
كل وثيقة لها حقل language ومرجع canonicalPost يشير إلى الأصل الإنجليزي. إليك استعلام GROQ لجلب منشور وجميع ترجماته:
// جلب منشور وجميع ترجماته
*[_type == "post" && slug.current == "sanity-cms-guide" && language == "en"][0]{
title,
language,
"translations": *[
_type == "post" &&
canonicalPost._ref == ^._id
]{
title,
language,
"slug": slug.current
}
}جانب المخطط مباشر — حقل language مع قائمة من اللغات المدعومة:
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(),
})أمر تعلمناه بالطريقة الصعبة: انشر الوثيقة الإنجليزية أولاً، ثم رقّع مراجع canonicalPost في الترجمات باستخدام معرف الوثيقة المنشورة — وليس بادئة drafts.. يعامل Sanity الوثائق المسودة والمنشورة ككيانات منفصلة داخلياً.
لمزيد من التفاصيل حول كيفية اتصال هذا الخط بـ Model Context Protocol، راجع القسم التالي.
ميزات الذكاء الاصطناعي في Sanity: MCP وCanvas وAgent Context
يضع Sanity نفسه كنظام تشغيل المحتوى لعصر الذكاء الاصطناعي. تشمل ميزات الذكاء الاصطناعي الرئيسية خادم MCP ليتمكن وكلاء الذكاء الاصطناعي من قراءة المحتوى وكتابته، وCanvas للتحرير بمساعدة الذكاء الاصطناعي داخل Studio، وAgent Context لوكلاء الذكاء الاصطناعي الإنتاجيين للاستعلام عن المحتوى المنظم مع الوعي بالمخطط.
تكامل خادم MCP
يتيح خادم MCP الخاص بـ Sanity لوكلاء الذكاء الاصطناعي — Claude Code وCursor وWindsurf وغيرها — التفاعل مع مساحة عمل Sanity برمجياً. يمكن للوكلاء قراءة المخططات وتنفيذ استعلامات GROQ وإنشاء وثائق وإدارة المحتوى بدون غلافات API مخصصة.
نستخدم خادم Sanity MCP يومياً في خط نشر المحتوى الخاص بنا. يستعلم وكلاء الذكاء الاصطناعي لدينا عن المخطط لفهم هيكل الوثيقة، ويجلبون المنشورات الموجودة لإيجاد فرص الربط الداخلي، وينشرون وثائق جديدة. يمنح بروتوكول MCP الوكلاء وعياً بالمخطط — يعرفون ما هي الحقول الموجودة وما هي الأنواع التي تتوقعها وما هي قواعد التحقق المطبقة. إذا كنت تبني وكلاء ذكاء اصطناعي لأعمالك، فهذا نمط قوي.
Agent Context للذكاء الاصطناعي الإنتاجي
Agent Context ميزة منفصلة لتكاملات الذكاء الاصطناعي على مستوى الإنتاج. على خلاف خادم MCP (المصمم لأدوات المطورين)، يوفر Agent Context وصولاً للقراءة فقط ومحدود النطاق لوكلاء الذكاء الاصطناعي التي تحتاج إلى الاستعلام عن محتواك في وقت التشغيل — فكّر في روبوتات الدردشة وأنظمة التوصيات وأنظمة تخصيص المحتوى.
الفرق مهم: MCP للتطوير وسير عمل التحرير (أدوات تطوير مدركة للمخطط)، بينما Agent Context للوصول إلى المحتوى في وقت التشغيل مع مصادقة صحيحة وتحديد للمعدل.
المحتوى المنظم لـ Sanity يمنحه ميزة حقيقية هنا. موقع WordPress يخزن المحتوى ككتل HTML — يجب على وكيل الذكاء الاصطناعي تحليل HTML لفهم المحتوى. Sanity يخزن وثائق JSON مكتوبة بمخططات محددة. يمكن لوكيل الاستعلام عن *[_type == "product" && category == "electronics"]{name, price, features} والحصول على بيانات نظيفة ومنظمة. لا استخراج، لا تحليل، لا تخمين.
كيف نستخدم Sanity في Techsy
هذا ليس قسماً نظرياً. نشغّل Sanity CMS عبر 4 مواقع إنتاجية، وننشر بـ 10 لغات مع خط نشر آلي بنيناه خلال العام الماضي. إليك البنية.
بنية خط نشر المحتوى لدينا
يمتد الخط من البحث إلى المنشور المنشور عبر جميع اللغات العشر:
- البحث — تحليل الكلمات المفتاحية وتحديد الفجوات في محتوى المنافسين وأنماط SERP
- الملخص — مواصفة كتابة منظمة مع توجيه القسم وأعداد الكلمات والروابط الداخلية
- الكتابة — إنتاج Markdown بالإنجليزية مع YAML frontmatter
- التحويل — سكريبت Python يحوّل Markdown إلى Portable Text JSON مع أنواع كتلنا المخصصة الخمسة
- النشر — استدعاءات API إلى Sanity:
createOrReplaceللوثيقة ورفع صور إلى Sanity CDN وترقيع مراجع المؤلف/الفئة - الترجمة — ترجمة بالذكاء الاصطناعي إلى 9 لغات مع التحقق من الاكتمال
- نشر الترجمات — نفس تدفق التحويل/النشر لكل لغة مع ترقيع مرجع
canonicalPostللأصل الإنجليزي
يدعم المخطط المخصص أنواع block وtable وcodeBlock وchartBlock وinlineImage — كلها معرّفة كـ schema objects إنتاجية لـ Sanity مع قواعد تحقق. من بين أفضل أدوات الذكاء الاصطناعي للشركات الناشئة التي اختبرناها، كان خط النشر القائم على Sanity الأكثر موثوقية للمحتوى المنظم على نطاق واسع.
دروس من 400+ قطعة محتوى منشورة
بعض الأشياء التي نتمنى لو أخبرنا بها أحد:
ترتيب ترقيع المراجع مهم. لا يمكن أن تشير مراجع Sanity إلى وثائق غير موجودة بعد. انشر المنشور الإنجليزي أولاً، ثم أنشئ الترجمات مع canonicalPost يشير إلى معرف الوثيقة الإنجليزية المنشورة. كسرنا هذا عدة مرات في البداية.
نشر المخطط لكل مساحة عمل بشكل منفصل. إذا شغّلت مشاريع Sanity متعددة (نشغّل 4)، تحتاج إلى نشر المخططات لكل منها بشكل منفصل: npx sanity@latest schema deploy لكل تهيئة مشروع.
الطبقة المجانية حقيقية. شغّلنا اثنين من مواقعنا الأربعة على الخطة المجانية لأشهر. 20 مستخدماً و500K طلب API/شهر و100K طلب CDN — هذا كافٍ لموقع إنتاجي حقيقي، وليس مجرد مشروع تجريبي.
تحويل Portable Text هو نقطة الاختناق. Markdown إلى Portable Text ليس أمراً تافهاً. قوائم متداخلة وجداول داخل blockquotes وكتل كود بأحرف خاصة — حالات حافة في كل مكان. كنا نكرر سكريبت المحوّل الخاص بنا لأشهر.
هل تحتاج مساعدة في إعداد Sanity لمشروعك؟ قمنا ببناء خطوط نشر محتوى متعددة اللغات لـ 4 مواقع إنتاجية. احصل على استشارة مجانية
تفصيل أسعار Sanity CMS
يقدم Sanity ثلاث خطط: مجانية (20 مستخدم و500K طلب API/شهر) ونمو ($15/مستخدم/شهر مع أدوار متقدمة ومسودات مجدولة) وخطة المؤسسات (تسعير مخصص مع SLA وميزات الامتثال). الطبقة المجانية هي الأسخى في سوق headless CMS.
| الميزة | مجانية | نمو ($15/مستخدم/شهر) | مؤسسات |
|---|---|---|---|
| المستخدمون | 20 | 50 | غير محدود |
| طلبات API | 500K/شهر | 2.5M/شهر | مخصص |
| طلبات CDN | 100K/شهر | 500K/شهر | مخصص |
| الأدوار | المسؤول فقط | المسؤول والمطور والمحرر والمساهم | أدوار مخصصة |
| التعاون | تحرير فوري | + نشر مجدول ومسودات | + سير عمل |
| الدعم | مجتمع | بريد إلكتروني | مخصص + SLA |
| الامتثال | -- | -- | SOC 2 وHIPAA |
على الطبقة المجانية، نشغّل اثنين من مواقعنا دون الوصول للحدود. أضافت خطة النمو بـ $15/مستخدم/شهر الوصول المبني على الأدوار (مهم بمجرد وجود محررين غير تقنيين) والنشر المجدول. المشاهدون مجانيون على خطة النمو، وهو لمسة جيدة — لا عقوبة على منح أصحاب المصلحة وصول للقراءة.
كيف يقارن هذا بالمنافسين؟
| الميزة | Sanity مجانية | Contentful مجانية | Strapi Cloud مجانية | Payload Cloud |
|---|---|---|---|---|
| المستخدمون | 20 | 1 | 1 | 1 |
| أنواع المحتوى | غير محدود | 48 | غير محدود | غير محدود |
| طلبات API | 500K/شهر | مشمولة | مشمولة | مشمولة |
| أنواع مخصصة | نعم | محدودة | نعم | نعم |
| سعر للنمو | $15/مستخدم/شهر | $300/شهر | $29/شهر | $50/شهر |
الطبقة المجانية بـ 20 مستخدماً في Sanity استثنائية. Contentful يقصرك على مستخدم واحد في المجانية ويقفز إلى $300/شهر لخطة الفريق. إذا كنت شركة ناشئة أو فريقاً صغيراً، تتيح لك الخطة المجانية لـ Sanity تشغيل أعباء عمل إنتاجية حقيقية دون إنفاق أي شيء.
يقدم Sanity أيضاً برنامجاً للشركات الناشئة يمنح الشركات المؤهلة سنة واحدة من وصول النمو مجاناً. يستحق التقديم إذا كنت مؤهلاً.
الأسئلة الشائعة
ما هو Sanity CMS وكيف يعمل؟
Sanity CMS منصة محتوى headless تخزن وثائق JSON منظمة في خلفية مُدارة تُسمى Content Lake. تحرّر المحتوى عبر Sanity Studio (تطبيق React قابل للتخصيص)، وتستعلم عنه بـ GROQ أو GraphQL، وتعرضه في أي إطار عمل frontend. يتزامن المحتوى في الوقت الفعلي عبر جميع العملاء المتصلين.
هل Sanity CMS مجاني؟
نعم. تتضمن الطبقة المجانية من Sanity 20 مستخدماً و500K طلب API شهرياً و100K طلب CDN — أسخى خطة مجانية بين منصات headless CMS. تكلف خطة النمو $15 لكل مستخدم شهرياً وتضيف الوصول المبني على الأدوار والنشر المجدول وحدوداً أعلى. تسعير المؤسسات مخصص.
ما الفرق بين Sanity وContentful؟
يستخدم Sanity schema-as-code (المخططات تعيش في قاعدة الكود)، وGROQ للاستعلام، وStudio مفتوح المصدر قابل للتخصيص بالكامل. يستخدم Contentful نمذجة المحتوى بواجهة رسومية، وGraphQL، ومحرراً مستضافاً مع تخصيص أقل. تتضمن الطبقة المجانية لـ Sanity 20 مستخدماً مقابل مستخدم واحد في Contentful. لـ Contentful سوق مكونات إضافية أكبر.
هل Sanity CMS مناسب للمبتدئين؟
Sanity Studio بديهي لمحرري المحتوى — تجربة التحرير لا تتطلب معرفة تقنية. إلا أن إعداد المخططات يتطلب إتقان JavaScript أو TypeScript. يوفر Sanity توثيقاً ممتازاً وقوالب مشاريع ومجتمع Slack مع دعم نشط. ابدأ بـ npm create sanity@latest وقالب مدونة.
هل يمكنني استضافة Sanity ذاتياً؟
Sanity Studio قابل للاستضافة الذاتية بالكامل لأنه تطبيق React مفتوح المصدر. يمكنك نشره على Vercel أو Netlify أو أي مزود استضافة ثابت. Content Lake الخلفية خدمة مُدارة — لا يوجد خيار للاستضافة الذاتية لطبقة البيانات. هذا مقايضة: تحصل على صفر إدارة للبنية التحتية لكن بدون تحكم في البيانات المحلية.
ما نوع قاعدة البيانات التي يستخدمها Sanity؟
Content Lake الخاص بـ Sanity ليس قاعدة بيانات SQL أو NoSQL تقليدية. إنه مخزن وثائق مُدار يخزن المحتوى كـ JSON منظم مع طبقة استعلام GROQ فوقه. لا تتفاعل مع قاعدة البيانات الأساسية مباشرة — تتفاعل عبر APIs الخاصة بـ Sanity. الوثائق لها تاريخ إصدار كامل ومزامنة فورية مدمجة.
هل Sanity CMS مفتوح المصدر؟
Sanity Studio مفتوح المصدر تحت رخصة MIT — يمكنك تفريعه وتخصيصه واستضافته ذاتياً. Content Lake الخلفية SaaS ملكية. مواصفة لغة استعلام GROQ أيضاً مفتوحة المصدر ومنشورة على GitHub. مواصفة Portable Text أيضاً مفتوحة المصدر، يُصانها على portabletext.org.
ما هو Portable Text في Sanity؟
Portable Text هي مواصفة Sanity للنص الغني المنظم. بدلاً من تخزين المحتوى كسلاسل HTML، تمثّل الفقرات والعناوين والصور والكتل المخصصة كـ JSON مكتوب في مصفوفة. هذا يجعل المحتوى محمولاً عبر الأطر والمنصات. يمكنك تعريف أنواع كتل مخصصة مثل أكواد البرمجة والمخططات والجداول مع حقولها المنظمة الخاصة.
ما هو GROQ وكيف يختلف عن GraphQL؟
GROQ (Graph-Relational Object Queries) هي لغة الاستعلام الأصلية لـ Sanity. صيغتها — *[filter]{projection} — أكثر إيجازاً من GraphQL لبيانات Sanity، مع دعم مدمج للربط عبر المعامل -> والحقول المحسوبة. GraphQL متاح أيضاً للفرق التي تفضل أدوات موحدة أو تستخدم Apollo Client بالفعل.
كيف يتعامل Sanity مع المحتوى متعدد اللغات؟
يدعم Sanity التعريب على مستوى الوثيقة (وثائق منفصلة لكل لغة مرتبطة بمراجع canonical) والتعريب على مستوى الحقل (حقول مترجمة داخل وثيقة واحدة). مستوى الوثيقة أفضل لـ SEO لأن كل ترجمة تحصل على URL وبيانات وصفية خاصة بها. نستخدم التعريب على مستوى الوثيقة للنشر عبر 10 لغات مع خطوط ترجمة ونشر آلية.