Techsy
Liên hệ
Bắt đầu
Quay lại Blog
guides

Hướng dẫn Sanity CMS: Cách chúng tôi xuất bản nội dung bằng 10 ngôn ngữ

Viết bởi Mert Batur Gürbüz
Apr 6, 2026
25 phút đọc
Mục lục
Hướng dẫn Sanity CMS: Cách chúng tôi xuất bản nội dung bằng 10 ngôn ngữ

Hướng dẫn Sanity CMS: Cách chúng tôi xuất bản nội dung bằng 10 ngôn ngữ

Chúng tôi đã xuất bản hơn 400 bài viết trên 4 website và 10 ngôn ngữ thông qua Sanity CMS. Dưới đây là những bài học chúng tôi rút ra, từ thiết kế schema đến quy trình xuất bản đa ngôn ngữ tự động.

Sanity CMS là một nền tảng nội dung headless (phi đầu cuối) được xây dựng xung quanh nội dung có cấu trúc, Content Lake thời gian thực và một trình soạn thảo tùy chỉnh dựa trên React gọi là Sanity Studio. Nó sử dụng GROQ để truy vấn, Portable Text cho nội dung phong phú và schema-as-code (schema dưới dạng mã) để mô hình hóa nội dung. Hướng dẫn này bao gồm cách thiết lập, thiết kế schema, GROQ, Portable Text, kiến trúc đa ngôn ngữ và bảng giá.

Sanity CMS là gì?

Sanity là một nền tảng nội dung có cấu trúc, hay như đội ngũ Sanity.io gọi là "hệ điều hành nội dung". Khác với các CMS truyền thống lưu trữ các khối HTML trong cơ sở dữ liệu, Sanity lưu trữ từng phần nội dung dưới dạng JSON có cấu trúc trong một backend được quản lý gọi là Content Lake. Bạn truy vấn nó bằng GROQ hoặc GraphQL, và hiển thị nội dung trên bất kỳ frontend nào bạn muốn: Next.js, React Native, Svelte, ứng dụng di động, công cụ CLI, hoặc bất cứ thứ gì khác.

Các công ty sử dụng nó trải dài trên mọi quy mô. Nike, Figma, Puma và Cloudflare vận hành Sanity ở quy mô doanh nghiệp. Các startup sử dụng nó vì gói miễn phí thực sự hữu ích (sẽ nói thêm về giá cả sau). Chúng tôi sử dụng nó vì không có giải pháp nào khác mang lại sự linh hoạt để xây dựng một quy trình xuất bản 10 ngôn ngữ hoàn toàn tự động.

Kiến trúc Content Lake

Content Lake là backend được quản lý của Sanity. Hãy nghĩ về nó như một kho lưu trữ tài liệu được host, đồng bộ hóa theo thời gian thực trên tất cả các client được kết nối. Khi một biên tập viên thay đổi một đoạn văn trong Sanity Studio, một biên tập viên khác sẽ thấy ngay lập tức, không cần nút lưu, không xung đột merge, không cần migration cơ sở dữ liệu.

Bên dưới, các tài liệu được lưu trữ dưới dạng JSON có cấu trúc với các trường được định kiểu. Mọi thay đổi đều được theo dõi thông qua nhật ký giao dịch, vì vậy bạn có đầy đủ lịch sử phiên bản theo mặc định. Tính năng đồng bộ hóa thời gian thực sử dụng kiến trúc dựa trên listener (được mô tả trong tài liệu kiến trúc GitHub của Sanity) đẩy các thay đổi đến tất cả người đăng ký thông qua RxJS observables.

Điều gì làm cho nó khác biệt so với, ví dụ, cơ sở dữ liệu PostgreSQL với API REST? Content Lake xử lý mô hình hóa nội dung, kiểm soát truy cập, bộ nhớ đệm CDN, biến đổi hình ảnh và cộng tác thời gian thực như một dịch vụ được quản lý duy nhất. Bạn không chạy migration. Bạn không quản lý các bản sao. Bạn chỉ cần định nghĩa schema và truy vấn nội dung.

Sanity Studio: Trình soạn thảo tùy chỉnh của bạn

Sanity Studio là một ứng dụng React mã nguồn mở đóng vai trò là giao diện chỉnh sửa của bạn. Nó không phải là một bảng quản trị được host sẵn, mà là một ứng dụng React nằm trong codebase của bạn. Bạn có thể tùy chỉnh mọi khía cạnh của nó: các component input tùy chỉnh, trường có điều kiện, hành động tài liệu, các mẫu structure builder và plugin.

Cộng tác thời gian thực được tích hợp sẵn. Nhiều biên tập viên có thể làm việc trên cùng một tài liệu cùng lúc với các chỉ báo hiện diện và cập nhật trực tiếp. Nếu bạn đã sử dụng Google Docs, trải nghiệm cũng tương tự, bạn thấy con trỏ và thay đổi của người khác trong thời gian thực.

Chúng tôi triển khai Studio của mình với npx sanity deploy, giúp host nó trên CDN của Sanity tại một subdomain tùy chỉnh. Bạn cũng có thể tự host vì nó chỉ là một ứng dụng React. Chúng tôi đánh giá cao Sanity trong bài so sánh headless CMS chủ yếu nhờ vào sự linh hoạt của Studio.

Cách thiết lập dự án Sanity

Để thiết lập Sanity CMS, hãy cài đặt CLI bằng npm create sanity@latest, chọn một mẫu dự án, cấu hình các file schema và chạy npx sanity dev để khởi chạy Studio cục bộ. Toàn bộ quá trình mất chưa đầy 5 phút.

Điều kiện tiên quyết và Cài đặt

Bạn cần Node.js 18+ và npm (hoặc pnpm). Chỉ vậy thôi. Chạy lệnh init:

bash
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 sẽ tạo khung dự án với mọi thứ bạn cần. Đây là cấu trúc dự án trông như thế nào:

Giải thích cấu trúc dự án

text
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.json

File sanity.config.ts là điểm entry point. Đây là một ví dụ tối giản:

typescript
// 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() cung cấp cho bạn một sân chơi GROQ ngay trong Studio, bạn sẽ sử dụng nó liên tục trong quá trình phát triển.

Triển khai Studio của bạn

Khởi chạy cục bộ với npx sanity dev (chạy trên localhost:3333). Khi bạn sẵn sàng chia sẻ với các biên tập viên, hãy triển khai lên CDN của Sanity:

bash
npx sanity deploy
# Prompts for a hostname, e.g., "my-blog"
# Deploys to https://my-blog.sanity.studio

Mẹo chuyên nghiệp: chạy npx sanity@latest schema deploy sau bất kỳ thay đổi schema nào. Thao tác này tải schema của bạn lên API của Sanity, cho phép các tính năng như API GraphQL và các công cụ nhận biết schema (bao gồm cả máy chủ MCP mà chúng tôi sẽ đề cập sau).

Thiết kế Schema trong Sanity CMS

Các schema của Sanity được định nghĩa là các đối tượng JavaScript hoặc TypeScript trong codebase của bạn. Mỗi schema chỉ định một loại tài liệu với các trường, quy tắc xác thực và các component input tùy chỉnh. Các thay đổi đối với schema diễn ra tức thì, không cần migration cơ sở dữ liệu. Đây là cách tiếp cận "schema-as-code", và đó là điều đã thuyết phục chúng tôi chọn Sanity thay vì Contentful.

Các loại trường và Xác thực

Sanity đi kèm với một bộ loại trường phong phú. Dưới đây là những loại chúng tôi sử dụng nhiều nhất:

Loại trườngTrường hợp sử dụngVí dụ
stringVăn bản ngắn, tiêu đề, slugTiêu đề bài viết, tên tác giả
textVăn bản thuần túy nhiều dòngĐoạn trích, mô tả
numberSố nguyên, số thập phânThời gian đọc, thứ tự sắp xếp
booleanBật/tắtCờ nổi bật, trạng thái nháp
arrayDanh sách, văn bản phong phú (Portable Text)Nội dung chính, thẻ tag
referenceLiên kết đến các tài liệu khácTác giả, danh mục
imageHình ảnh với metadataẢnh bìa với văn bản alt
slugChuỗi thân thiện với URLTự động tạo từ tiêu đề
objectNhóm trường lồng nhauCác trường SEO (metaTitle + metaDescription)
date / datetimeNgày thángNgày xuất bản

Mọi trường đều hỗ trợ xác thực thông qua callback validation. Bạn có thể bắt buộc các trường bắt buộc, giá trị min/max, mẫu regex và các quy tắc tùy chỉnh:

typescript
defineField({
  name: 'seoDescription',
  title: 'Meta Description',
  type: 'string',
  validation: (Rule) =>
    Rule.required()
      .min(145)
      .max(160)
      .warning('Meta description should be 145-160 characters'),
})

Các loại Block tùy chỉnh (Ví dụ thực tế của chúng tôi)

Đây là nơi Sanity trở nên thú vị, và là nơi 0 trên 6 hướng dẫn cạnh tranh hiển thị bất kỳ mã nào. Trong schema production của chúng tôi, chúng tôi định nghĩa năm loại block tùy chỉnh bên trong mảng body: block (văn bản chuẩn), table, codeBlock, chartBlock và inlineImage.

Đây là định nghĩa codeBlock của chúng tôi:

typescript
// 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',
    },
  ],
})

Và đây là cách trường body tham chiếu đến tất cả các loại tùy chỉnh của chúng tôi cùng nhau:

typescript
// 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
  ],
})

Điều này cung cấp cho các biên tập viên của chúng tôi một bộ công cụ nội dung phong phú trong khi giữ cho mọi phần tử được định kiểu và có thể truy vấn. Một chartBlock không chỉ là một embed HTML mờ ám, mà là dữ liệu có cấu trúc với các trường chartType, title, dataPoints và dataLabels. Điều đó rất quan trọng khi bạn cố gắng hiển thị cùng một nội dung trên web, email và di động.

Các phương pháp hay nhất về tổ chức Schema

Giữ các schema модуль hóa. Chúng tôi chia nhỏ chúng theo loại qua các file: schemas/documents/post.ts, schemas/objects/codeBlock.ts, schemas/objects/chartBlock.ts. Nhập tất cả chúng trong schemas/index.ts:

typescript
// 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]

Bài học quan trọng chúng tôi rút ra khi làm việc với nội dung có cấu trúc: schema CỦA BẠN CHÍNH LÀ mô hình nội dung. Nếu bạn coi nó như kỹ thuật ngữ cảnh cho đội ngũ nội dung của mình, bạn sẽ đưa ra các quyết định thiết kế tốt hơn. Mỗi trường bạn thêm vào nên phục vụ một mục đích, dù là cho biên tập viên, cho việc hiển thị hay cho việc truy vấn.

GROQ: Ngôn ngữ truy vấn của Sanity

GROQ (Graph-Relational Object Queries) là ngôn ngữ truy vấn mã nguồn mở của Sanity để lọc, join và chiếu các tài liệu JSON. Cú pháp cơ bản là *[filter]{projection}, chọn tất cả các tài liệu khớp với bộ lọc, sau đó định hình đầu ra. Nó ngắn gọn hơn GraphQL cho các truy vấn cụ thể của Sanity và, theo kinh nghiệm của chúng tôi, dễ học hơn.

Truy vấn cơ bản: Lọc và Chiếu

Truy vấn đơn giản nhất lấy tất cả các tài liệu của một loại:

groq
// 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
}

Toán tử -> đi theo các reference. author->name có nghĩa là "đi theo reference tác giả và trả về trường name." Không có truy vấn riêng biệt, không có vấn đề N+1, không có JOIN, tất cả đều là một biểu thức duy nhất.

Joins, Sắp xếp và Phân trang

Đối với các trang index blog của chúng tôi, chúng tôi cần các bài viết được sắp xếp, phân trang với các reference được mở rộng:

groq
// 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] cung cấp cho bạn 10 kết quả đầu tiên (chỉ số 0, kết thúc độc quyền). | order(publishedAt desc) sắp xếp mới nhất trước. Projection định hình đầu ra để bao gồm chính xác những gì frontend của bạn cần, không hơn không kém.

Bạn có thể kiểm tra tất cả các truy vấn này một cách tương tác bằng cách sử dụng plugin Vision bên trong Sanity Studio. Nó vô giá trong quá trình phát triển. Để biết thêm các mẫu, hãy xem bảng cheatsheet GROQ.

GROQ so với GraphQL

Sanity hỗ trợ cả GROQ và GraphQL. Khi nào nên sử dụng cái nào?

GROQ là ngôn ngữ gốc của Sanity. Nó xử lý joins, projections và các trường tính toán trong một chuỗi truy vấn duy nhất. Đó là những gì Content Lake được tối ưu hóa cho.

GraphQL có sẵn sau khi bạn triển khai schema của mình (npx sanity@latest schema deploy). Sử dụng nó khi bạn cần các công cụ tiêu chuẩn hóa, ví dụ: nếu frontend của bạn đã sử dụng Apollo Client hoặc nếu nhóm của bạn biết GraphQL nhưng không biết GROQ.

Chúng tôi sử dụng độc quyền GROQ. Nó biểu cảm hơn cho dữ liệu Sanity và plugin Vision giúp việc gỡ lỗi truy vấn trở nên tầm thường.

Portable Text: Nội dung phong phú đúng cách

Portable Text là đặc tả của Sanity cho văn bản phong phú có cấu trúc. Thay vì lưu trữ nội dung dưới dạng chuỗi HTML, nó lưu trữ một mảng các block được định kiểu, đoạn văn, tiêu đề, hình ảnh, đoạn mã, bảng, mỗi cái như một đối tượng JSON. Điều này làm cho nội dung có thể hiển thị trong bất kỳ framework nào, bất kỳ nền tảng nào, bất kỳ định dạng nào.

Cấu trúc dữ liệu

Dưới đây là cách một đoạn văn và một block mã trông như thế nào dưới dạng 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({ ... })"
  }
]

Mỗi block có _type và _key. Các block văn bản chuẩn sử dụng "block" với các children spans (hỗ trợ các marks như đậm, nghiêng và liên kết). Các block tùy chỉnh, như codeBlock, chartBlock, table và inlineImage của chúng tôi, sử dụng _type riêng và mang các trường có cấu trúc.

Tại sao điều này lại quan trọng? Vì HTML là một định dạng hiển thị, không phải định dạng lưu trữ. Nếu bạn lưu trữ <h2>Title</h2><p>Some <strong>text</strong></p> trong cơ sở dữ liệu, bạn đã tự khóa mình vào việc hiển thị web. Bạn không thể trích xuất sạch sẽ điều đó cho ứng dụng di động, bản tin email, PDF hoặc cửa sổ ngữ cảnh của tác nhân AI. Portable Text tách biệt nội dung khỏi trình bày. Đặc tả Portable Text là mã nguồn mở, nó không phải là sự phụ thuộc vào Sanity.

Các Block tùy chỉnh trong Production

Quy trình của chúng tôi chuyển đổi Markdown sang Portable Text bằng một script Python (scripts/md_to_portable_text.py). Bộ chuyển đổi xử lý các block chuẩn, cộng với bốn loại tùy chỉnh của chúng tôi:

  • table, sử dụng schema plugin @sanity/table. Các hàng và ô được lưu trữ dưới dạng dữ liệu có cấu trúc.
  • codeBlock, ngôn ngữ và mã là các trường riêng biệt, cho phép tô sáng cú pháp khi hiển thị.
  • chartBlock, loại biểu đồ, tiêu đề, nhãn trục, tên series và các điểm dữ liệu dưới dạng JSON có cấu trúc. Frontend hiển thị những thứ này bằng Chart.js.
  • inlineImage, văn bản alt, nguồn và chú thích tùy chọn là các trường riêng biệt.

Cấu trúc này có nghĩa là chúng tôi có thể truy vấn tất cả các ví dụ mã trong blog của mình (*[body[]._type == "codeBlock"]), tìm các bài viết có biểu đồ hoặc trích xuất tất cả các hình ảnh thiếu văn bản alt, tất cả thông qua GROQ.

Hiển thị Portable Text

Trên frontend, sử dụng @portabletext/react (hoặc các tương đương Svelte/Vue). Bạn đăng ký các component tùy chỉnh cho mỗi loại block:

tsx
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} />

Đó là toàn bộ quy trình hiển thị. Component PortableText xử lý các block chuẩn (đoạn văn, tiêu đề, danh sách, marks) tự động. Bạn chỉ cần định nghĩa các component tùy chỉnh cho các loại tùy chỉnh của mình.

Nội dung đa ngôn ngữ với Sanity CMS

Sanity hỗ trợ nội dung đa ngôn ngữ thông qua bản địa hóa cấp tài liệu (các tài liệu riêng biệt cho mỗi ngôn ngữ được liên kết bằng một reference canonical) hoặc bản địa hóa cấp trường (các trường được dịch trong một tài liệu). Bản địa hóa cấp tài liệu hoạt động tốt hơn cho SEO và xuất bản quy mô lớn, đó là những gì chúng tôi sử dụng trên quy trình 10 ngôn ngữ của mình.

Bản địa hóa cấp Tài liệu so với cấp Trường

Khía cạnhCấp Tài liệuCấp Trường
Cách tiếp cậnTài liệu riêng cho mỗi ngôn ngữTất cả bản dịch trong một tài liệu
SEOMỗi tài liệu có URL/slug riêngURL duy nhất, khó phục vụ các trang theo ngôn ngữ
Độ phức tạp truy vấnBộ lọc đơn giản: language == "de"Truy cập trường lồng nhau: title.de
Kích thước nội dungTài liệu nhỏ, tập trungMột tài liệu lớn với tất cả ngôn ngữ
Phù hợp nhất choBài đăng blog, trang, nội dung hướng SEOChuỗi UI nhỏ, nhãn, metadata
Kết luận của chúng tôiChúng tôi sử dụng cái này cho mọi thứChỉ cho các chuỗi UI chia sẻ

Chúng tôi chọn bản địa hóa cấp tài liệu vì mỗi bản dịch có slug riêng, URL riêng và metadata riêng. Phiên bản tiếng Thổ Nhĩ Kỳ của một bài viết về Supabase so với Firebase có slug supabase-firebase-karsilastirma, tiếng Thổ Nhĩ Kỳ chuẩn, không phải một hack tham số URL.

Kiến trúc Quy trình 10 Ngôn ngữ của chúng tôi

Đây là cách quy trình tự động của chúng tôi hoạt động: chúng tôi viết một bài đăng bằng tiếng Anh, sau đó dịch nó sang 9 ngôn ngữ bổ sung (Tiếng Đức, Pháp, Hà Lan, Tây Ban Nha, Thổ Nhĩ Kỳ, Ý, Thụy Điển, Na Uy, Ả Rập). Mỗi bản dịch đi qua chuyển đổi Markdown, tạo Portable Text và xuất bản API Sanity.

Kiến trúc trông như thế này:

  1. Viết, Markdown tiếng Anh với frontmatter YAML
  2. Dịch, dịch AI sang 9 ngôn ngữ (đã xác minh tính đầy đủ và dấu phụ)
  3. Chuyển đổi, script Python chuyển đổi mỗi file .md sang JSON Portable Text
  4. Xuất bản, gọi API đến Sanity: tạo tài liệu, tải lên hình ảnh, patch các reference

Mỗi tài liệu có một trường language và một reference canonicalPost trỏ đến bản gốc tiếng Anh. Đây là truy vấn GROQ để lấy một bài đăng và tất cả các bản dịch của nó:

groq
// 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
  }
}

Phía schema khá đơn giản, một trường language với enum các ngôn ngữ được hỗ trợ:

typescript
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(),
})

Một vấn đề chúng tôi đã học được một cách khó khăn: hãy xuất bản tài liệu tiếng Anh trước, sau đó patch các reference canonicalPost trên các bản dịch bằng ID tài liệu đã xuất bản, không phải tiền tố drafts.. Sanity coi các tài liệu nháp và đã xuất bản là các thực thể riêng biệt bên trong.

Để biết thêm chi tiết về cách quy trình này kết nối với Model Context Protocol, hãy xem phần tiếp theo.

Các tính năng AI của Sanity: MCP, Canvas và Agent Context

Sanity định vị mình là hệ điều hành nội dung cho kỷ nguyên AI. Các tính năng AI chính bao gồm máy chủ MCP để các tác nhân AI đọc và ghi nội dung, Canvas để chỉnh sửa hỗ trợ bởi AI bên trong Studio và Agent Context để các tác nhân AI production truy vấn nội dung có cấu trúc với nhận thức về schema.

Tích hợp Máy chủ MCP

Máy chủ Sanity MCP cho phép các tác nhân AI, Claude Code, Cursor, Windsurf và những tác nhân khác, tương tác với không gian làm việc Sanity của bạn một cách lập trình. Các tác nhân có thể đọc schema, thực thi truy vấn GROQ, tạo tài liệu và quản lý nội dung mà không cần các wrapper API tùy chỉnh.

Chúng tôi sử dụng máy chủ Sanity MCP hàng ngày trong quy trình nội dung của mình. Các tác nhân AI của chúng tôi truy vấn schema để hiểu cấu trúc tài liệu, tìm nạp các bài đăng hiện có để tìm cơ hội liên kết nội bộ và xuất bản các tài liệu mới. Giao thức MCP cung cấp cho các tác nhân nhận thức về schema, họ biết những trường nào tồn tại, những loại nào họ mong đợi và những quy tắc xác thực nào áp dụng. Nếu bạn đang xây dựng các quy trình làm việc tác nhân AI cho doanh nghiệp, đây là một mẫu mạnh mẽ.

Agent Context cho AI Production

Agent Context là một tính năng riêng biệt cho các tích hợp AI cấp production. Không giống như máy chủ MCP (được thiết kế cho các công cụ dành cho nhà phát triển), Agent Context cung cấp quyền truy cập chỉ đọc, được giới hạn phạm vi cho các tác nhân AI cần truy vấn nội dung của bạn trong thời gian chạy, hãy nghĩ đến chatbot, công cụ đề xuất hoặc hệ thống cá nhân hóa nội dung.

Sự khác biệt là quan trọng: MCP dành cho các quy trình làm việc build-time và biên tập (công cụ phát triển nhận biết schema), trong khi Agent Context dành cho truy cập nội dung runtime với xác thực và giới hạn tốc độ phù hợp.

Nội dung có cấu trúc của Sanity mang lại lợi thế thực sự ở đây. Một trang WordPress lưu trữ nội dung dưới dạng các khối HTML, một tác nhân AI phải phân tích cú pháp HTML để hiểu nội dung. Sanity lưu trữ các tài liệu JSON được định kiểu với các schema được định nghĩa. Một tác nhân có thể truy vấn *[_type == "product" && category == "electronics"]{name, price, features} và nhận lại dữ liệu sạch, có cấu trúc. Không cào quét, không phân tích cú pháp, không đoán mò.

Cách chúng tôi sử dụng Sanity tại Techsy

Đây không phải là phần giả định. Chúng tôi vận hành Sanity CMS trên 4 website production, xuất bản bằng 10 ngôn ngữ với một quy trình tự động mà chúng tôi đã xây dựng trong năm qua. Đây là kiến trúc.

Kiến trúc Quy trình Nội dung của chúng tôi

Quy trình đi từ nghiên cứu đến bài đăng đã xuất bản trên tất cả 10 ngôn ngữ:

  1. Nghiên cứu, phân tích từ khóa, xác định khoảng trống đối thủ, mẫu SERP
  2. Brief, đặc tả viết có cấu trúc với hướng dẫn phần, số lượng từ, liên kết nội bộ
  3. Viết, tạo Markdown tiếng Anh với frontmatter YAML
  4. Chuyển đổi, script Python biến đổi Markdown sang JSON Portable Text với 5 loại block tùy chỉnh của chúng tôi
  5. Xuất bản, gọi API đến Sanity: tài liệu createOrReplace, tải lên hình ảnh lên Sanity CDN, patch các reference tác giả/danh mục
  6. Dịch, dịch AI sang 9 ngôn ngữ, đã xác minh tính đầy đủ
  7. Xuất bản bản dịch, cùng quy trình chuyển đổi/xuất bản cho mỗi ngôn ngữ, với reference canonicalPost được patch đến bản gốc tiếng Anh

Schema tùy chỉnh hỗ trợ các loại block, table, codeBlock, chartBlock và inlineImage, tất cả được định nghĩa là các đối tượng schema Sanity production với các quy tắc xác thực. Trong số các công cụ AI cho startup mà chúng tôi đã thử nghiệm, quy trình dựa trên Sanity này là đáng tin cậy nhất cho nội dung có cấu trúc ở quy mô lớn.

Bài học từ hơn 400 bài viết đã xuất bản

Một vài điều chúng tôi ước ai đó đã nói với chúng tôi:

Thứ tự patch reference là quan trọng. Các reference của Sanity không thể trỏ đến các tài liệu chưa tồn tại. Hãy xuất bản bài đăng tiếng Anh trước, sau đó tạo các bản dịch với canonicalPost trỏ đến ID đã xuất bản của tài liệu tiếng Anh. Chúng tôi đã phá vỡ điều này nhiều lần trong giai đoạn đầu.

Triển khai schema là theo workspace. Nếu bạn chạy nhiều dự án Sanity (chúng tôi chạy 4), bạn cần triển khai schema cho từng dự án riêng biệt: npx sanity@latest schema deploy cho mỗi cấu hình dự án.

Gói miễn phí là có thật. Chúng tôi đã chạy hai trong số bốn trang web của mình trên gói miễn phí trong nhiều tháng. 20 người dùng, 500K yêu cầu API/tháng, 100K yêu cầu CDN, đủ cho một trang web production thực sự, không chỉ là một dự án đồ chơi.

Chuyển đổi Portable Text là nút cổ chai. Chuyển đổi Markdown sang Portable Text không hề tầm thường. Danh sách lồng nhau, bảng bên trong blockquote, block mã với các ký tự đặc biệt, các trường hợp edge ở khắp mọi nơi. Chúng tôi đã lặp lại script chuyển đổi của mình trong nhiều tháng.

Cần giúp đỡ thiết lập Sanity cho dự án của bạn? Chúng tôi đã xây dựng các quy trình nội dung đa ngôn ngữ cho 4 trang web production. Nhận tư vấn miễn phí

Phân tích Giá cả Sanity CMS

Sanity cung cấp ba gói: Free (20 người dùng, 500K yêu cầu API/tháng), Growth ($15/người dùng/tháng với các vai trò nâng cao và bản nháp lên lịch) và Enterprise (giá tùy chỉnh với SLA và các tính năng tuân thủ). Gói miễn phí là hào phóng nhất trên thị trường headless CMS.

Tính năngFreeGrowth ($15/người dùng/tháng)Enterprise
Người dùng2050Không giới hạn
Yêu cầu API500K/tháng2.5M/thángTùy chỉnh
Yêu cầu CDN100K/tháng500K/thángTùy chỉnh
Vai tròChỉ AdminAdmin, Developer, Editor, ContributorVai trò tùy chỉnh
Cộng tácChỉnh sửa thời gian thực+ Xuất bản theo lịch, bản nháp+ Quy trình làm việc
Hỗ trợCộng đồngEmailDedicated + SLA
Tuân thủ,,SOC 2, HIPAA

Trên gói miễn phí, chúng tôi chạy hai trang web của mình mà không chạm đến giới hạn. Gói Growth ở mức $15/người dùng/tháng đã thêm quyền truy cập dựa trên vai trò (quan trọng khi chúng tôi có các biên tập viên không kỹ thuật) và xuất bản theo lịch. Người xem miễn phí trên gói Growth, đó là một điểm cộng nice, bạn không bị phạt vì cung cấp quyền đọc cho các bên liên quan.

So sánh với đối thủ như thế nào?

Tính năngSanity FreeContentful FreeStrapi Cloud FreePayload Cloud
Người dùng20111
Loại nội dungKhông giới hạn48Không giới hạnKhông giới hạn
Gọi API500K/thángBao gồmBao gồmBao gồm
Loại tùy chỉnhCóGiới hạnCóCó
Giá để mở rộng$15/người dùng/tháng$300/tháng$29/tháng$50/tháng

Gói miễn phí 20 người dùng của Sanity là ngoại lệ. Contentful giới hạn bạn ở 1 người dùng trên gói miễn phí và nhảy vọt lên $300/tháng cho gói Team của họ. Nếu bạn là một startup hoặc nhóm nhỏ, gói miễn phí của Sanity cho phép bạn chạy các khối lượng công việc production thực sự mà không tốn xu nào.

Sanity cũng cung cấp một chương trình startup tặng các startup đủ điều kiện một năm truy cập Growth miễn phí. Đáng để nộp đơn nếu bạn đủ điều kiện.

Câu hỏi Thường gặp

Sanity CMS là gì và nó hoạt động như thế nào?

Sanity CMS là một nền tảng nội dung headless lưu trữ các tài liệu JSON có cấu trúc trong một backend được quản lý gọi là Content Lake. Bạn chỉnh sửa nội dung thông qua Sanity Studio (một ứng dụng React tùy chỉnh), truy vấn nó bằng GROQ hoặc GraphQL và hiển thị nó trong bất kỳ framework frontend nào. Nội dung đồng bộ hóa theo thời gian thực trên tất cả các client được kết nối.

Sanity CMS có miễn phí không?

Có. Gói miễn phí của Sanity bao gồm 20 người dùng, 500K yêu cầu API mỗi tháng và 100K yêu cầu CDN, là gói miễn phí hào phóng nhất trong số các nền tảng headless CMS. Gói Growth có giá $15 mỗi người dùng mỗi tháng và thêm quyền truy cập dựa trên vai trò, xuất bản theo lịch và các giới hạn cao hơn. Giá Enterprise là tùy chỉnh.

Sự khác biệt giữa Sanity và Contentful là gì?

Sanity sử dụng schema-as-code (schema nằm trong codebase của bạn), GROQ để truy vấn và một Studio mã nguồn mở hoàn toàn tùy chỉnh. Contentful sử dụng mô hình hóa nội dung dựa trên GUI, GraphQL và một trình soạn thảo được host với ít tùy chỉnh hơn. Gói miễn phí của Sanity bao gồm 20 người dùng so với 1 của Contentful. Contentful có thị trường plugin lớn hơn.

Sanity CMS có tốt cho người mới bắt đầu không?

Sanity Studio trực quan cho các biên tập viên nội dung, trải nghiệm chỉnh sửa không yêu cầu kiến thức kỹ thuật. Tuy nhiên, thiết lập schema đòi hỏi thành thạo JavaScript hoặc TypeScript. Sanity cung cấp tài liệu tuyệt vời, các mẫu dự án và một Slack cộng đồng với hỗ trợ tích cực. Hãy bắt đầu với npm create sanity@latest và một mẫu blog.

Tôi có thể tự host Sanity không?

Sanity Studio hoàn toàn có thể tự host vì nó là một ứng dụng React mã nguồn mở. Bạn có thể triển khai nó lên Vercel, Netlify hoặc bất kỳ nhà cung cấp hosting tĩnh nào. Backend Content Lake là một dịch vụ được quản lý, không có tùy chọn tự host cho lớp dữ liệu. Đây là sự đánh đổi: bạn có được quản lý hạ tầng bằng không nhưng không có quyền kiểm soát dữ liệu on-premises.

Sanity sử dụng loại cơ sở dữ liệu nào?

Content Lake của Sanity không phải là cơ sở dữ liệu SQL hoặc NoSQL truyền thống. Nó là một kho lưu trữ tài liệu được quản lý lưu trữ nội dung dưới dạng JSON có cấu trúc với một lớp truy vấn GROQ ở trên. Bạn không tương tác trực tiếp với cơ sở dữ liệu bên dưới, bạn tương tác thông qua các API của Sanity. Các tài liệu có đầy đủ lịch sử phiên bản và đồng bộ hóa thời gian thực được tích hợp sẵn.

Sanity CMS có mã nguồn mở không?

Sanity Studio là mã nguồn mở theo giấy phép MIT, bạn có thể fork, tùy chỉnh và tự host nó. Backend Content Lake là SaaS độc quyền. Đặc tả ngôn ngữ truy vấn GROQ cũng là mã nguồn mở, được công bố trên GitHub. Đặc tả Portable Text cũng là mã nguồn mở, được duy trì tại portabletext.org.

Portable Text trong Sanity là gì?

Portable Text là đặc tả của Sanity cho văn bản phong phú có cấu trúc. Thay vì lưu trữ nội dung dưới dạng chuỗi HTML, nó đại diện cho các đoạn văn, tiêu đề, hình ảnh và các block tùy chỉnh dưới dạng các đối tượng JSON được định kiểu trong một mảng. Điều này làm cho nội dung có thể di chuyển giữa các framework và nền tảng. Bạn có thể định nghĩa các loại block tùy chỉnh như đoạn mã, biểu đồ và bảng với các trường có cấu trúc riêng của chúng.

GROQ là gì và nó khác với GraphQL như thế nào?

GROQ (Graph-Relational Object Queries) là ngôn ngữ truy vấn gốc của Sanity. Cú pháp của nó, *[filter]{projection}, ngắn gọn hơn GraphQL cho dữ liệu Sanity, với hỗ trợ tích hợp cho các joins thông qua toán tử -> và các trường tính toán. GraphQL cũng có sẵn cho các nhóm thích các công cụ tiêu chuẩn hóa hoặc đã sử dụng Apollo Client.

Sanity xử lý nội dung đa ngôn ngữ như thế nào?

Sanity hỗ trợ bản địa hóa cấp tài liệu (các tài liệu riêng biệt cho mỗi ngôn ngữ được liên kết bằng các reference canonical) và bản địa hóa cấp trường (các trường được dịch trong một tài liệu). Cấp tài liệu tốt hơn cho SEO vì mỗi bản dịch có URL và metadata riêng. Chúng tôi sử dụng bản địa hóa cấp tài liệu để xuất bản trên 10 ngôn ngữ với các quy trình dịch và xuất bản tự động.

Thẻ

sanity-cmsheadless-cmsgroqportable-textquan-ly-noi-dung

Chia sẻ bài viết này

Bài viết liên quan

Thêm từ chuyên mục guides

guides
Jul 18, 2026

So sánh giá LLM API 2026: Định giá mọi mô hình lớn

Bảng so sánh giá LLM API đầy đủ cho năm 2026 — Claude, GPT-5.6, Gemini, DeepSeek, Qwen, GLM và Mistral được định giá song song theo mỗi triệu token, lấy trực tiếp từ các trang giá chính thức.

12 min read phút đọc
Đọc
guides
Apr 12, 2026

Hướng dẫn Surfer SEO 2026: Trình soạn thảo nội dung, Chấm điểm NLP và Tìm kiếm AI

Hướng dẫn thực hành về Surfer SEO bao gồm quy trình làm việc với Trình soạn thảo nội dung, hệ thống chấm điểm NLP, AI Tracker để tối ưu hóa GEO và tự động hóa API. Dựa trên quá trình thử nghiệm hơn 50 bài viết.

14 min read phút đọc
Đọc
guides
Apr 12, 2026

Hướng dẫn Semrush 2026: Giải thích mọi công cụ (Kèm ví dụ)

Hướng dẫn thực tế về Semrush bao gồm nghiên cứu từ khóa, kiểm tra trang web, phân tích đối thủ, theo dõi khả năng hiển thị AI và thiết lập máy chủ MCP. Bao gồm các ví dụ mã và quy trình làm việc từ hệ thống SEO thực tế.

14 min read phút đọc
Đọc
Xem tất cả bài viết
Khởi động dự án của bạn

Sẵn sàng tạo nên điều gì đó đột phá?

Hãy biến tầm nhìn của bạn thành hiện thực. Đội ngũ của chúng tôi sẵn sàng đồng hành cùng bạn tạo ra phần mềm tạo nên sự khác biệt.

Đặt lịch gọi ý tưởng 30 phútXem dự án của chúng tôi

Công cụ hot trong kho

Claude Skills

Xem tất cả
  • New Post

    Full SEO blog pipeline: research, brief, write, validate, image, translate, publish to Sanity. Autonomous from start to finish.

  • Content Refresh

    Audit a stale post, find decay drivers, and ship a SERP-aligned refresh without losing existing rankings.

  • SEO Audit

    Site-wide SEO audit with prioritized fix list: technical, on-page, and EEAT signals.

Tự động hoá AI

Xem tất cả
  • Security Auditor

    Weekly SCA + IaC scan with prioritized fix PRs.

  • Cold Email Writer

    Generates first-touch emails grounded in one specific public detail.

  • Lead Research Agent

    Enrich an email into a profile, score fit, alert in Slack.

Công cụ hot trong kho

Claude Skills

Xem tất cả
  • New Post

    Full SEO blog pipeline: research, brief, write, validate, image, translate, publish to Sanity. Autonomous from start to finish.

  • Content Refresh

    Audit a stale post, find decay drivers, and ship a SERP-aligned refresh without losing existing rankings.

  • SEO Audit

    Site-wide SEO audit with prioritized fix list: technical, on-page, and EEAT signals.

Tự động hoá AI

Xem tất cả
  • Security Auditor

    Weekly SCA + IaC scan with prioritized fix PRs.

  • Cold Email Writer

    Generates first-touch emails grounded in one specific public detail.

  • Lead Research Agent

    Enrich an email into a profile, score fit, alert in Slack.

Dịch vụ

  • Giải pháp doanh nghiệp
  • Ứng dụng di động
  • Ứng dụng web

Giải pháp

  • Hệ thống CRM
  • Tích hợp AI
  • Giải pháp ERP
  • Voice Agent
  • Tự động hóa quy trình
  • Bảo mật thông tin

Thư viện

  • Blog
  • Dự án

Cộng đồng

  • Tự động hoá AI
  • Claude Skills

Công cụ

  • Tính phí làm ứng dụng mobile
  • Tính phí dùng OpenAI / LLM API
  • Tính phí làm MVP
  • Tính phí làm Voice AI Agent

Công ty

  • Giới thiệu
  • Cộng sự
  • Liên hệ

Pháp lý

  • Chính sách quyền riêng tư
  • Điều khoản dịch vụ
  • Chính sách cookie

Dịch vụ

  • Giải pháp doanh nghiệp
  • Ứng dụng di động
  • Ứng dụng web

Giải pháp

  • Hệ thống CRM
  • Tích hợp AI
  • Giải pháp ERP
  • Voice Agent
  • Tự động hóa quy trình
  • Bảo mật thông tin

Thư viện

  • Blog
  • Dự án

Cộng đồng

  • Tự động hoá AI
  • Claude Skills

Công cụ

  • Tính phí làm ứng dụng mobile
  • Tính phí dùng OpenAI / LLM API
  • Tính phí làm MVP
  • Tính phí làm Voice AI Agent

Công ty

  • Giới thiệu
  • Cộng sự
  • Liên hệ
Pháp lýChính sách quyền riêng tưĐiều khoản dịch vụChính sách cookie
TECHSY
© 2026 Techsy. Bảo lưu mọi quyền.