sanity-io avatar

Portable Text Serialization

If you're rendering Sanity's Portable Text in any frontend framework, this covers the component mapping pattern that's consistent across React, Svelte, Vue, Astro, and server-side HTML. The skill breaks down the block structure (marks, markDefs, listItem levels) and shows you how to map custom types like images or code blocks so they actually render instead of disappearing silently. It includes framework-specific rules for each major library, plus a quick reference for community serializers in React Native, PHP, Python, and others. The emphasis on keeping your components object stable and handling missing types explicitly will save you from common re-render bugs and silent failures when content editors add new block types.

skills.sh installs
3K
GitHub stars
197
last updated
Aug 21, 2026

Install

$ npx -y skills add sanity-io/agent-toolkit --skill portable-text-serialization --agent claude-code

Installs into .claude/skills of the current project.

Files

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)

Sponsors

Details

Repository
github.com/sanity-io/agent-toolkit
Categories
Frontend Development, Backend & APIs, AI & Agent Building, Debugging
First seen
Jun 3, 2026

More from sanity-io/agent-toolkit

All 7
1freshtechbro avataranimejsfreshtechbro/claudedesignskillsVersatile JavaScript animation engine for DOM, CSS, SVG, and JavaScript objects. Use when creating timeline-based animations, stagger effects, SVG morphing, key3Kskills.sh installs
2jezweb avatarux-auditjezweb/claude-skillsWalk through a live web app AS a real user to find usability + behavioural bugs that static reviews miss. REQUIRES proof of interaction (typing, clicking, sendi3Kskills.sh installs
3nexu-io avatarweb-artifacts-buildernexu-io/open-designBuild complex claude.ai HTML artifacts with React and Tailwind. Anthropic's reference workflow for shipping rich, embeddable artifacts.3Kskills.sh installs
4triggerdotdev avatartrigger-realtimetriggerdotdev/skillsSubscribe to Trigger.dev task runs in real-time from frontend and backend. Use when building progress indicators, live dashboards, streaming AI/LLM responses, o2.9Kskills.sh installs
5nexu-io avatarartifacts-buildernexu-io/open-designSuite of tools for creating elaborate, multi-component claude.ai HTML artifacts using modern frontend web technologies (React, Tailwind CSS, shadcn/ui).2.9Kskills.sh installs
6nexu-io avatardigits-fintech-swiss-templatenexu-io/open-designSwiss-grid fintech deck template in black / warm paper / neon-lime contrast. Use when users ask for premium data-story slides with strict modular layout, bold n2.9Kskills.sh installs