# @sanity/block-tools

> Can format HTML, Slate JSON or Sanity block array into any other format.

Latest version **3.70.0** (published 2025-01-14) · MIT license · 0 weekly downloads

> **Deprecated.** This package is deprecated.

## Install

```sh
npm install @sanity/block-tools
pnpm add @sanity/block-tools
yarn add @sanity/block-tools
bun add @sanity/block-tools
```

## Health

**Score 10/100 (F)** — status: deprecated.

Negative: deprecated.

## Facts

| | |
|---|---|
| Version | 3.70.0 |
| Published | 2025-01-14 |
| First published | 2017-11-02 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | ESM + CommonJS |
| Dependencies | 3 |
| Unpacked size | 442 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Provenance | attested (GitHub Actions) |
| GitHub stars | 6377 |
| Author | Sanity.io <hello@sanity.io> |
| Maintainers | kmelve, bjoerge, rexxars, skogsmaskin, tonina, mattcraig, joneidejohnsen, rubioz, robinpyon, mariuslundgard, sanity-io, evenw, radhe_sanity, rbotten, danielsgroves, judofyr, ryanblock, obliadp, dcilke, madken, fredcarlsen, hermanw, tambet, sgulseth, atombender, simeonsanity, stipsan, snorreeb, rankers, rdunk, michael-sanity, vincentquigley, ritasdias, kenjonespizza, rneatherway-sanity, josh_sanity_io, cngonzalez-sanity, jjburbridge, tdfka_rick, svirs, ryanbonial-sanity, indrek.karner, ash, sergeisarviro, refiito, drewsanity, kaspar.lippmaa.sanity, dam, simen.svale, tbeseda, daniel.malmer, jordanl17, colepeters, armandocerna, joan_miralles_paez, christianhg, pedro-sanity, jwoods-sanity, ricokahler, tiit.kass.saity, binoy14, pauloborgesf, ausha, nuurtamo, chrislarocquesanity, rostimelk, mattlewine.sanity |
| Keywords | sanity, cms, headless, realtime, content, block-tools |

## Links

- npm: https://www.npmjs.com/package/@sanity/block-tools
- Repository: https://github.com/sanity-io/sanity
- Homepage: https://www.sanity.io/
- Issues: https://github.com/sanity-io/sanity/issues
- npm.io page: https://npm.io/package/@sanity/block-tools

## Dependencies (3)

- [lodash](https://npm.io/package/lodash.md) ^4.17.21
- [@sanity/types](https://npm.io/package/@sanity/types.md) 3.70.0
- [get-random-values-esm](https://npm.io/package/get-random-values-esm.md) 1.0.2

## Alternatives

- [@opentelemetry/exporter-zipkin](https://npm.io/package/@opentelemetry/exporter-zipkin.md) — 14.8M weekly downloads
- [pusher-js](https://npm.io/package/pusher-js.md) — 2.0M weekly downloads
- [browserify](https://npm.io/package/browserify.md) — 1.7M weekly downloads
- [sqs-consumer](https://npm.io/package/sqs-consumer.md) — 1.7M weekly downloads
- [@sanity/eventsource](https://npm.io/package/@sanity/eventsource.md) — 930.8K weekly downloads

## Recent versions

- 3.70.0 (latest) — 2025-01-14
- 3.69.1-corel.489 (corel) — 2025-01-08
- 3.68.4-export-comments.33 (export-comments) — 2025-01-02
- 3.67.2-content-os.38 (content-os) — 2024-12-17
- 3.67.1-next.2 (next) — 2024-12-11
- 3.66.2-upgrade-vite-v6.23 (upgrade-vite-v6) — 2024-12-09
- 3.66.2-upgrade-vite-v5.30 (upgrade-vite-v5) — 2024-12-09
- 3.65.2-cops.39 (cops) — 2024-12-03
- 3.64.4-search24.53 (search24) — 2024-11-29
- 3.64.2-react-compiler.0 (react-compiler) — 2024-11-14
- 2.36.6 (v2) — 2024-11-07
- 3.62.1-manifests.36 (manifests) — 2024-10-23
- 3.59.2-canary.33 (canary) — 2024-10-07
- 3.57.4-memoized-form-state.18 (memoized-form-state) — 2024-09-16
- 3.54.1-ref-focus-repro.4 (ref-focus-repro) — 2024-08-20
- … 1278 more at https://npm.io/package/@sanity/block-tools/versions

## README

# Sanity Block Tools

> **⚠ This package is deprecated**
>
> Please note that this package is deprecated and has been replaced by [@portabletext/block-tools](https://www.npmjs.com/package/@portabletext/block-tools)

Various tools for processing Sanity block content. Mostly used internally in the Studio code, but it got some nice functions (especially `htmlToBlocks`) which is handy when you are importing data from HTML into your dataset as block text.

**NOTE:** To use `@sanity/block-tools` in a Node.js script, you will need to provide a `parseHtml` method - generally using `JSDOM`. [Read more](#jsdom-example).

## Example

Let's start with a complete example:

```js
import {Schema} from '@sanity/schema'
import {htmlToBlocks, getBlockContentFeatures} from '@sanity/block-tools'

// 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!'
//      }
//    ]
//  }

// Get the feature-set of a blockContentType
const features = getBlockContentFeatures(blockContentType)
```

## Methods

### `htmlToBlocks(html, blockContentType, options)` (html deserializer)

This will deserialize the input html (string) into blocks.

#### Params

##### `html`

The stringified version of the HTML you are importing

##### `blockContentType`

A 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](https://github.com/sanity-io/sanity/blob/243b4a5686a1293a8a977574a5cabc768ec01725/packages/%40sanity/block-tools/src/constants.ts#L24-L78) 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:

```js
{
  _type: 'block',
  style: 'normal'
  children: [
    {
      _type: 'span'
      text: 'Hello world!'
    }
  ]
}
```

##### `options` (optional)

###### `parseHtml`

The 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.

###### JSDOM example

```js
const {JSDOM} = require('jsdom')
const {htmlToBlocks} = require('@sanity/block-tools')

const blocks = htmlToBlocks('<html><body><h1>Hello world!</h1><body></html>', blockContentType, {
  parseHtml: (html) => new JSDOM(html).window.document,
})
```

##### `rules`

You may add your own rules to deal with special HTML cases.

```js
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.

```js
import {normalizeBlock} from '@sanity/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: []
}
```

### `getBlockContentFeatures(blockContentType)`

Will return an object with the features enabled for the input block content type.

```js
{
  annotations: [{title: 'Link', value: 'link'}],
  decorators: [
    {title: 'Strong', value: 'strong'},
    {title: 'Emphasis', value: 'em'},
    {title: 'Code', value: 'code'},
    {title: 'Underline', value: 'underline'},
    {title: 'Strike', value: 'strike-through'}
  ],
  styles: [
    {title: 'Normal', value: 'normal'},
    {title: 'Heading 1', value: 'h1'},
    {title: 'H2', value: 'h2'},
    {title: 'H3', value: 'h3'},
    {title: 'H4', value: 'h4'},
    {title: 'H5', value: 'h5'},
    {title: 'H6', value: 'h6'},
    {title: 'Quote', value: 'blockquote'}
  ]
}
```

---
_Source: https://npm.io/package/@sanity/block-tools · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
