mcpField
P
portable-text-conversion

portable-text-conversion

github.com/sanity-ioData & databases1942.8k installsUpdated 1d ago
Repository

About portable-text-conversion

A guide to converting external content into Sanity Portable Text. It helps developers choose a Markdown or HTML conversion path, or construct Portable Text blocks manually from other sources.

Key features

  1. 01Convert Markdown with markdownToPortableText
  2. 02Convert HTML with htmlToBlocks
  3. 03Build Portable Text blocks manually
  4. 04Explains block, span, mark, and list structure
  5. 05Separate conversion rules by source format

Use cases

  1. 01Migrating Markdown content into Sanity
  2. 02Converting HTML during a content migration
  3. 03Constructing Portable Text from APIs or databases

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/sanity-io/agent-toolkit --skill portable-text-conversion

After installing, type/portable-text-conversionin Claude Code to confirm it loaded.

Bundled files

References and scripts installed along with SKILL.md.

rules/
html-to-pt.md
manual-construction.md
markdown-to-pt.md

Details

From the project README

Portable Text Conversion

Convert external content (HTML, Markdown) into Portable Text for Sanity. Three main approaches:

  1. markdownToPortableText — Convert Markdown directly using @portabletext/markdown (recommended for Markdown)
  2. htmlToBlocks — Parse HTML into PT blocks using @portabletext/block-tools (for HTML migration)
  3. Manual construction — Build PT blocks directly from any source (APIs, databases, etc.)

Portable Text Specification

Understand the target format before converting. PT is an array of blocks:

[
  {
    "_type": "block",
    "_key": "abc123",
    "style": "normal",
    "children": [
      {"_type": "span", "_key": "def456", "text": "Hello ", "marks": []},
      {"_type": "span", "_key": "ghi789", "text": "world", "marks": ["strong"]}
    ],
    "markDefs": []
  },
  {
    "_type": "block",
    "_key": "jkl012",
    "style": "h2",
    "children": [
      {"_type": "span", "_key": "mno345", "text": "A heading", "marks": []}
    ],
    "markDefs": []
  },
  {
    "_type": "image",
    "_key": "pqr678",
    "asset": {"_type": "reference", "_ref": "image-abc-200x200-png"}
  }
]

Key rules:

  • Every block and span needs _key (unique within the array)
  • _type: "block" is for text blocks; custom types use their own _type
  • markDefs holds annotation data; marks on spans reference markDefs[*]._key or are decorator strings
  • Lists use listItem ("bullet" | "number") and level (1, 2, 3...) on regular blocks

Conversion Rules

Read the rule file matching your source format:

  • Markdown → Portable Text: rules/markdown-to-pt.md — @portabletext/markdown with markdownToPortableText (recommended)
  • HTML → Portable Text: rules/html-to-pt.md — @portabletext/block-tools with htmlToBlocks
  • Manual PT Construction: rules/manual-construction.md — build blocks programmatically from any source

Note: @sanity/block-tools is the legacy package name. Always use @portabletext/block-tools for new projects. The API is the same.

Comments

Markdown supported