
Grab your gear: The official Sanity swag store
Read Grab your gear: The official Sanity swag storeBased on the documentation, here's how to convert Sanity block content to HTML while preserving anchor tags:
@portabletext/to-html (Modern Approach)The @sanity/block-content-to-html package you mentioned is deprecated. The modern replacement is @portabletext/to-html.
Here's how to use it and preserve links:
import {toHTML} from '@portabletext/to-html'
const portableText = [/* your block content from Sanity */]
const html = toHTML(portableText, {
components: {
marks: {
link: ({value, children}) => {
const href = value?.href || ''
const target = value?.blank ? ' target="_blank" rel="noopener"' : ''
return `<a href="${href}"${target}>${children}</a>`
}
}
}
})If you're using mark annotations for internal links, you'll need to join the reference data in your GROQ query first:
*[_type == "post"]{
...,
body[]{
...,
markDefs[]{
...,
_type == "internalLink" => {
"slug": @.reference->slug
}
}
}
}Then serialize with a custom component:
const html = toHTML(portableText, {
components: {
marks: {
internalLink: ({value, children}) => {
const slug = value?.slug?.current || ''
return `<a href="/${slug}">${children}</a>`
},
link: ({value, children}) => {
return `<a href="${value?.href || ''}">${children}</a>`
}
}
}
})marks component to customize how link annotations are renderedCheck out the full documentation on presenting Portable Text for more examples and the @portabletext/to-html GitHub repo for detailed usage.
Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.
Content operations
Content backend


The only platform powering content operations
By Industry


Tecovas strengthens their customer connections
Build and Share

Grab your gear: The official Sanity swag store
Read Grab your gear: The official Sanity swag store