
Security News
Open VSX Begins Implementing Pre-Publish Security Checks After Repeated Supply Chain Incidents
Following multiple malicious extension incidents, Open VSX outlines new safeguards designed to catch risky uploads earlier.
@portabletext/block-tools
Advanced tools
Can format HTML, Slate JSON or Sanity block array into any other format.
@portabletext/block-toolsVarious tools for processing Portable Text.
NOTE: To use @portabletext/block-tools in a Node.js script, you will need to provide a parseHtml method - generally using JSDOM. Read more.
Let's start with a complete example:
import {htmlToBlocks} from '@portabletext/block-tools'
import {Schema} from '@sanity/schema'
// Start with compiling a schema we can work against
const defaultSchema = Schema.compile({
name: 'myBlog',
types: [
{
type: 'object',
name: 'blogPost',
fields: [
{
title: 'Title',
type: 'string',
name: 'title',
},
{
title: 'Body',
name: 'body',
type: 'array',
of: [{type: 'block'}],
},
],
},
],
})
// The compiled schema type for the content type that holds the block array
const blockContentType = defaultSchema
.get('blogPost')
.fields.find((field) => field.name === 'body').type
// Convert HTML to block array
const blocks = htmlToBlocks(
'<html><body><h1>Hello world!</h1><body></html>',
blockContentType,
)
// Outputs
//
// {
// _type: 'block',
// style: 'h1'
// children: [
// {
// _type: 'span'
// text: 'Hello world!'
// }
// ]
// }
htmlToBlocks(html, blockContentType, options) (html deserializer)This will deserialize the input html (string) into blocks.
htmlThe stringified version of the HTML you are importing
blockContentTypeA compiled version of the block content schema type.
The deserializer will respect the schema when deserializing the HTML elements to blocks.
It only supports a subset of HTML tags. Any HTML tag not in the block-tools whitelist will be deserialized to normal blocks/spans.
For instance, if the schema doesn't allow H2 styles, all H2 HTML elements will be output like this:
{
_type: 'block',
style: 'normal'
children: [
{
_type: 'span'
text: 'Hello world!'
}
]
}
options (optional)parseHtmlThe HTML-deserialization is done by default by the browser's native DOMParser.
On the server side you can give the function parseHtml
that parses the html into a DOMParser compatible model / API.
const {JSDOM} = require('jsdom')
const {htmlToBlocks} = require('@portabletext/block-tools')
const blocks = htmlToBlocks(
'<html><body><h1>Hello world!</h1><body></html>',
blockContentType,
{
parseHtml: (html) => new JSDOM(html).window.document,
},
)
rulesYou may add your own rules to deal with special HTML cases.
htmlToBlocks(
'<html><body><pre><code>const foo = "bar"</code></pre></body></html>',
blockContentType,
{
parseHtml: (html) => new JSDOM(html),
rules: [
// Special rule for code blocks
{
deserialize(el, next, block) {
if (el.tagName.toLowerCase() != 'pre') {
return undefined
}
const code = el.children[0]
const childNodes =
code && code.tagName.toLowerCase() === 'code'
? code.childNodes
: el.childNodes
let text = ''
childNodes.forEach((node) => {
text += node.textContent
})
// Return this as an own block (via block helper function), instead of appending it to a default block's children
return block({
_type: 'code',
language: 'javascript',
text: text,
})
},
},
],
},
)
normalizeBlock(block, [options={}])Normalize a block object structure to make sure it has what it needs.
import {normalizeBlock} from '@portabletext/block-tools'
const partialBlock = {
_type: 'block',
children: [
{
_type: 'span',
text: 'Foobar',
marks: ['strong', 'df324e2qwe'],
},
],
}
normalizeBlock(partialBlock, {allowedDecorators: ['strong']})
Will produce
{
_key: 'randomKey0',
_type: 'block',
children: [
{
_key: 'randomKey00',
_type: 'span',
marks: ['strong'],
text: 'Foobar'
}
],
markDefs: []
}
Slate is a completely customizable framework for building rich text editors. It provides a more flexible and powerful approach to handling rich text compared to @portabletext/block-tools, which is more focused on the Portable Text format specifically.
Draft.js is a JavaScript rich text editor framework, built for React. It offers a similar set of tools for creating and manipulating rich text content, but it is more tightly integrated with React and does not specifically target the Portable Text format.
ProseMirror is a toolkit for building rich-text editors on the web. It provides a more general-purpose solution for rich text editing, with a focus on extensibility and customizability, whereas @portabletext/block-tools is specialized for Portable Text.
FAQs
Convert HTML to Portable Text with built-in support for Google Docs, Word, and Notion
The npm package @portabletext/block-tools receives a total of 344,555 weekly downloads. As such, @portabletext/block-tools popularity was classified as popular.
We found that @portabletext/block-tools demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 10 open source maintainers collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Following multiple malicious extension incidents, Open VSX outlines new safeguards designed to catch risky uploads earlier.

Research
/Security News
Threat actors compromised four oorzc Open VSX extensions with more than 22,000 downloads, pushing malicious versions that install a staged loader, evade Russian-locale systems, pull C2 from Solana memos, and steal macOS credentials and wallets.

Security News
Lodash 4.17.23 marks a security reset, with maintainers rebuilding governance and infrastructure to support long-term, sustainable maintenance.