Back to Skills

portable-text-conversion

Convert HTML and Markdown content into Portable Text blocks for Sanity. Use when migrating content from legacy CMSs, importing HTML or Markdown into Sanity, building content pipelines that ingest external content, converting rich text between formats, or programmatically creating Portable Text documents. Covers @portabletext/markdown (markdownToPortableText), @portabletext/block-tools (htmlToBlocks), custom deserializers, and the Portable Text specification for manual block construction.

175stars27forksUpdated 8/13/2026

Security Assessment

Safe(95/100)
Security Score95/100

About portable-text-conversion

This skill guides converting HTML and Markdown content into Portable Text, the structured rich-text format used by Sanity. It solves the recurring content-migration and ingestion problem of transforming legacy CMS output, Markdown docs, or arbitrary source data into valid Portable Text blocks that Sanity can store and render.

It presents three approaches: markdownToPortableText from @portabletext/markdown (recommended for Markdown), htmlToBlocks from @portabletext/block-tools (for HTML migration, with built-in handling for Google Docs, Word, and Notion content), and manual block construction from any source such as APIs or databases. The skill explains the Portable Text specification (blocks and spans, required _key values, styles, marks and markDefs annotations, and list handling) and provides working TypeScript examples: compiling a Sanity block content type with @sanity/schema, parsing HTML with JSDOM, writing custom deserializers for images, links, and iframes, pre-processing HTML to strip layout elements and extract metadata, uploading images to Sanity assets during migration rather than hotlinking, and a full migration that imports WordPress posts via sanity/migrate. It also notes that @portabletext/block-tools supersedes the legacy @sanity/block-tools package name.

It targets developers and content engineers building Sanity content pipelines, migrating from legacy CMSs, or programmatically generating documents. Use cases include one-time bulk imports, ongoing ingestion pipelines, and converting rich text between formats with full control over the resulting block structure.

FAQ

Which conversion approach should I use?

Use markdownToPortableText (@portabletext/markdown) for Markdown, htmlToBlocks (@portabletext/block-tools) for HTML migration, or manual block construction when building from arbitrary sources like APIs or databases.

What packages and setup are needed for HTML conversion?

Install @portabletext/block-tools, jsdom, and @sanity/schema. In Node you must provide a parseHtml function returning a DOM Document (via JSDOM) and a compiled Sanity block content type describing valid marks, styles, and custom types.

How are custom or non-standard HTML elements handled?

Through custom deserializer rules. The skill shows converting img to image blocks, a with custom attributes to link annotations, and iframe to embed blocks, plus pre-processing to remove headers, footers, nav, and scripts.

How should images be handled during migration?

Upload them to Sanity rather than linking external URLs. The skill provides an uploadImage helper using client.assets.upload and setting the asset reference on the image block.

Is @sanity/block-tools still valid?

It is the legacy package name with an identical API; the skill recommends @portabletext/block-tools for new projects.

All Files

4 files
rules/html-to-pt.md6.9 KB
View
rules/manual-construction.md4.9 KB
View
SKILL.md2.6 KB
View
rules/markdown-to-pt.md5.4 KB
View

Install portable-text-conversion

Download and extract the skill files to your .claude/skills/ directory.

Quick Setup:

  1. Copy the skill folder to .claude/skills/
  2. Claude will automatically detect and use the skill