Files
theater-ziefen-website/.agents/skills/portable-text-serialization/rules/markdown.md
T
johannes.gasser 57af0b8386
Build and Deploy / build-and-deploy (push) Successful in 2m53s
add skills
2026-05-18 08:39:42 +02:00

124 lines
3.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
title: Serialize Portable Text to Markdown
description: Convert Portable Text to Markdown strings using @portabletext/markdown
tags: [portable-text, markdown, serialization, conversion]
---
# Serialize Portable Text to Markdown
Use `@portabletext/markdown` to convert PT blocks to Markdown strings. Useful for AI/LLM pipelines, static site generators, README generation, and anywhere Markdown is the target format.
```bash
npm install @portabletext/markdown
```
## Basic Usage
```ts
import {portableTextToMarkdown} from '@portabletext/markdown'
const markdown = portableTextToMarkdown(portableTextBlocks)
```
## Built-in Support
Out of the box, `portableTextToMarkdown` handles:
- Headings (h1h6)
- Paragraphs
- Bold (`**`), italic (`_`), inline code (`` ` ``), strikethrough (`~~`)
- Links (`[text](url)`)
- Blockquotes (`>`)
- Ordered and unordered lists (including nested)
- Code blocks (fenced with language)
- Horizontal rules (`---`)
- Images (`![alt](url)`)
- Tables (GFM)
## Built-in Type Renderers
The library exports default renderers for common block object types. Enable them explicitly:
```ts
import {
portableTextToMarkdown,
DefaultCodeBlockRenderer,
DefaultImageRenderer,
DefaultHorizontalRuleRenderer,
DefaultTableRenderer,
DefaultHtmlRenderer,
} from '@portabletext/markdown'
const markdown = portableTextToMarkdown(blocks, {
types: {
'code': DefaultCodeBlockRenderer, // {code, language?} → fenced code block
'image': DefaultImageRenderer, // {src, alt?, title?} → ![alt](src "title")
'horizontal-rule': DefaultHorizontalRuleRenderer, // → ---
'table': DefaultTableRenderer, // {rows, headerRows?} → GFM table
'html': DefaultHtmlRenderer, // {html} → raw HTML
},
})
```
## Custom Renderers
Handle custom block types and marks with renderer functions:
```ts
const markdown = portableTextToMarkdown(blocks, {
// Custom block types — receives {value, index, isInline}
types: {
callout: ({value}) => `> **${value.title}**\n> ${value.text}`,
image: ({value, isInline}) => {
if (isInline) return ''
return `![${value.alt || ''}](${value.url})`
},
},
// Custom block style renderers — receives {value, children, index}
block: {
h1: ({children}) => `# ${children}`,
blockquote: ({children}) => `> ${children}`,
},
// Custom mark renderers — receives {value, children, text, markType, markKey}
marks: {
highlight: ({children}) => `==${children}==`,
internalLink: ({children, value}) => `[${children}](/docs/${value.slug})`,
},
// Custom list item renderer — receives {value, children, listIndex}
listItem: ({children}) => children,
// Control spacing between blocks — function, not string
blockSpacing: ({current, next}) => {
if (current.listItem && next.listItem) return '\n'
return undefined // use default (\n\n)
},
// Handle unknown types gracefully
unknownType: ({value}) => `<!-- Unknown type: ${value._type} -->`,
unknownMark: ({children}) => children,
})
```
## Use Cases
| Use Case | Why Markdown |
|----------|-------------|
| AI/LLM context | Models work well with Markdown input |
| Static site generators | Hugo, Jekyll, Eleventy consume Markdown |
| README generation | Generate docs from Sanity content |
| Email (with converter) | Markdown → HTML for email templates |
| Export/backup | Human-readable content export |
| Documentation pipelines | Sanity as docs CMS, output as Markdown |
## Bidirectional: Also Converts Markdown → PT
The same package also provides `markdownToPortableText()` for the reverse direction. See the `portable-text-conversion` skill for details.
## Reference
- [@portabletext/markdown](https://github.com/portabletext/editor/tree/main/packages/markdown)
- Part of the [portabletext/editor](https://github.com/portabletext/editor) monorepo