All skills
sanity-io avatar

/portable-text-serialization

@a11c399 official
by Sanitysanity-io/agent-toolkit187 stars
30

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.

Use this Skill: https://skilld.dev/gh/sanity-io/agent-toolkit/portable-text-serialization

This session only. Nothing lands on disk.

rulesplain-text.md

≈425 tokens on demand. Your agent reads this file only when SKILL.md points to it.

Extract Plain Text from Portable Text

Every @portabletext/* library exports a toPlainText() utility. Use it for meta descriptions, search indexing, summaries, and anywhere you need raw text without markup.

Usage

// From any framework library:
import {toPlainText} from '@portabletext/react'
// or: import {toPlainText} from '@portabletext/svelte'
// or: import {toPlainText} from '@portabletext/vue'
// or: import {toPlainText} from '@portabletext/to-html'

const plainText = toPlainText(portableTextBlocks)

Common Patterns

Meta Description

function getMetaDescription(body: PortableTextBlock[]): string {
  const text = toPlainText(body)
  return text.length > 160 ? text.slice(0, 157) + '...' : text
}

Search Indexing

// Index document content for search
const searchableText = toPlainText(document.body)

Slug Generation

import slugify from 'slugify'

const slug = slugify(toPlainText(blocks), {lower: true, strict: true})

Character/Word Count

const text = toPlainText(blocks)
const wordCount = text.split(/\s+/).filter(Boolean).length
const charCount = text.length

Behavior

  • Extracts text from all span children in block type nodes
  • Joins blocks with double newlines (\n\n)
  • Ignores custom block types (images, code blocks, etc.)
  • Strips all marks (bold, links, etc.) — returns raw text only

Reference

Source: SKILL.md on GitHub

No alerts16d4 checks · Risk SAFE
  • Gen Agent Trust Hub16d

    The skill provides comprehensive reference guides, code patterns, and best practices for serializing and rendering Portable Text across several frontend frameworks (React, Svelte, Vue, Astro, HTML, Markdown). It implements secure coding recommendations, explicitly advising developers on how to prevent Cross-Site Scripting (XSS) vulnerabilities by sanitizing data and escaping HTML during server-side string generation.

  • Socket16d

    No alerts

  • Snyk16d

    Risk: LOW · No issues

  • ZeroLeaks5mo

    Score: 93/100 · 2 sections analyzed

Signed by skilld at a11c399. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 2 weeks ago.

Activeupdated 8 months ago
metadata
{
  "author": "sanity",
  "version": "1.0.0"
}
  • React
  • Vue
  • portable-text
  • sanity
  • svelte
  • astro
  • serialization
  • rendering
  • markdown
  • html

README badge

README badge for sanity-io/agent-toolkit/portable-text-serialization

Render Portable Text to React, Svelte, Vue, Astro, HTML, Markdown, and plain text using the @portabletext library family. Maps PT node types (blocks, marks, custom types) to framework-specific components, with rules and patterns for each target framework and guidance on custom serializers for non-standard block types.

Generated from the current SKILL.md.

Does this skill support rendering Portable Text in React, Vue, Svelte, and Astro?
Yes. The skill covers @portabletext/react, @portabletext/vue, @portabletext/svelte, and astro-portabletext, each following the same component-mapping pattern.
Can I convert Portable Text to HTML or Markdown server-side?
Yes. Use @portabletext/to-html for server-side HTML strings or @portabletext/markdown to convert to Markdown format.
How do I render custom block types like images or code blocks?
Custom types require explicit component mappings in the components object — they will not render by default. Map each custom _type to a renderer that receives the block's value as props.
Does this skill help with plain text extraction?
Yes. Use @portabletext/toolkit to extract plain text from Portable Text content.
What if my framework or target (React Native, Solid, PHP) isn't listed in the rules?
The skill documents the core component-mapping pattern used by all serializers and lists community packages for React Native, Solid, PHP, Python, and other languages on portabletext.org, though dedicated rule files are only provided for React, Vue, Svelte, Astro, HTML, and Markdown.

Generated from the current SKILL.md. These answers refresh after source changes.