Preserving HTML ID attributes in block content using the block tools library

5 replies
Last updated: Oct 26, 2022 I’m using the block tools
library to translate existing html to block content/portable text. I have html elements with important ID attributes that are being stripped out during the transformation process. Is there a way to preserve html id attributes in block content?
For example, this HTML

<p id="important">Important paragraph</p>
Results in this block content object (there is no id=“important” artifact anywhere here)

    "_type": "block",
    "markDefs": [],
    "style": "normal",
    "children": [
        "_type": "span",
        "marks": [],
        "text": "Important paragraph",
        "_key": "55a9bea915f10"
    "_key": "55a9bea915f1"
Oct 26, 2022, 9:56 PM
user Q
! Have you specified any rules to deal with these attributes?
Oct 26, 2022, 10:03 PM
Yes, my setup looks very similar to Mark’s code sandbox above.
I have rules like this…

    deserialize(el, _next, _block) {
      if (el.tagName.toLowerCase() !== "sup") {
        return undefined;
      return {
        _type: "span",
        marks: ["superscript"],
        text: el.textContent,
Do you have an example of what a rule to preserve ID attributes would look like? I’m surprised this is a “special HTML case” haha.
Oct 26, 2022, 10:09 PM
Got it! They won't be picked up by default since attributes on elements are usually visual concerns. You need a few things. First, you need a custom decorator set up in order for the PT editor in the Studio to display/edit the attribute. Second, you'd need to add logic to check for the attribute (which is likely
or something similar), then return an object like this:
  _type: 'span',
  marks: ['<custom-decorator-name>'],
  text: el.textContent
Oct 26, 2022, 10:33 PM
Great! Thanks for the links and example!
Oct 26, 2022, 11:14 PM
You're welcome!
Oct 26, 2022, 11:19 PM

Sanity– build remarkable experiences at scale

Sanity is a modern headless CMS that treats content as data to power your digital business. Free to get started, and pay-as-you-go on all plans.

Was this answer helpful?