Portable Text Serialization

作者 sanity-io88d6cdfa7cb0MIT收录于 2026年10月8日更新于 2026年10月8日

Render and serialize Portable Text to React, Svelte, Vue, Astro, HTML, Markdown, and plain text. Use when implementing Portable Text rendering in any frontend framework, building custom serializers for non-standard block types, converting Portable Text to HTML strings server-side, converting Portable Text to Markdown, extracting plain text from Portable Text, or troubleshooting rendering issues with marks, blocks, lists, or custom types.

AI 生成的概览

指导将 Sanity Portable Text 渲染和序列化为 React、Svelte、Vue、Astro、HTML、Markdown 和纯文本。

功能
该技能说明如何使用 @portabletext/* 系列库渲染 Portable Text 内容,介绍 Portable Text 的区块结构,以及针对 types、marks、block、list、listItem 和 hardBreak 的统一 components 映射模式。它指向 React、Svelte、Vue、Astro、HTML、Markdown 和纯文本提取的框架专属规则文件,并列出面向其他目标的社区序列化器。内容还涵盖常见做法,例如自定义类型组件、保持组件对象稳定、处理缺失组件,以及展开引用的 GROQ 查询。
适用场景
适用于在前端框架中实现 Portable Text 渲染、为非标准区块类型构建自定义序列化器、在服务端将 Portable Text 转换为 HTML 或 Markdown、提取纯文本,或排查 marks、区块、列表或自定义类型的渲染问题。
运行要求
仅为说明文档,不附带脚本。它引用 @portabletext/* 系列包(或 astro-portabletext 等框架对应包),查询时还需针对 Sanity 内容源使用 GROQ。

Portable Text Serialization

Render Portable Text content across frameworks using the @portabletext/* library family. Each library follows the same component-mapping pattern: you provide a components object that maps PT node types to framework-specific renderers.

Portable Text Structure (Quick Reference)

PT is an array of blocks. Each block has _type, optional style, children (spans), markDefs, listItem, and level.

Root array├── block (_type: "block")│   ├── style: "normal" | "h1" | "h2" | "blockquote" | ...│   ├── children: [span, span, ...]│   │   └── span: { _type: "span", text: "...", marks: ["strong", "<markDefKey>"] }│   ├── markDefs: [{ _key, _type: "link", href: "..." }, ...]│   ├── listItem: "bullet" | "number" (optional)│   └── level: 1, 2, 3... (optional, for nested lists)├── custom block (_type: "image" | "code" | any custom type)└── ...more blocks

Marks come in two forms:

  • Decorators: string values in marks[] like "strong", "em", "underline", "code"
  • Annotations: keys in marks[] referencing entries in markDefs[] (e.g., links, internal references)

Component Mapping Pattern (All Frameworks)

Every @portabletext/* library accepts a components object with these keys:

KeyRendersProps/Data
typesCustom block/inline types (image, code, CTA)value (the block data)
marksDecorators + annotationschildren + value (mark data)
blockBlock styles (h1, normal, blockquote)children
listList wrappers (ul, ol)children
listItemList itemschildren
hardBreakLine breaks within a block—

Framework-Specific Rules

Read the rule file matching your framework:

  • React / Next.js: rules/react.md — @portabletext/react or next-sanity
  • Svelte / SvelteKit: rules/svelte.md — @portabletext/svelte
  • Vue / Nuxt: rules/vue.md — @portabletext/vue
  • Astro: rules/astro.md — astro-portabletext
  • HTML (server-side): rules/html.md — @portabletext/to-html
  • Markdown: rules/markdown.md — @portabletext/markdown
  • Plain text extraction: rules/plain-text.md — @portabletext/toolkit

Additional Community Serializers

These are listed on portabletext.org but don't have dedicated rule files:

TargetPackage
React Native@portabletext/react-native-portabletext
React PDF@portabletext/react-pdf-portabletext
Solidsolid-portabletext
Qwikportabletext-qwik
Shopify Liquidportable-text-to-liquid
PHPsanity-php (SanityBlockContent class)
Pythonportabletext-html
C# / .NETdotnet-portable-text
Dart / Flutterflutter_sanity_portable_text

Common Patterns (All Frameworks)

Custom Types Need Explicit Components

PT renderers only handle standard blocks by default. Custom types (image, code, callToAction, etc.) require explicit component mappings — they won't render otherwise.

Keep Components Object Stable

In React/Vue, define components outside the render function or memoize it. Recreating on every render causes unnecessary re-renders.

Handle Missing Components Gracefully

All libraries accept onMissingComponent to control behavior when encountering unknown types:

  • false — suppress warnings
  • Custom function — log or report

Querying PT with GROQ

Always expand references inside custom blocks:

groq
body[]{  ...,  _type == "image" => {    ...,    asset->  },  markDefs[]{    ...,    _type == "internalLink" => {      ...,      "slug": @.reference->slug.current    }  }}

来源与署名

来源:sanity-io/agent-toolkit位于skills/portable-text-serialization提交88d6cdf

许可证: MIT

内容归原作者所有。SourceWeft 从公开仓库中收录这些内容。

举报或申请下架