Converting Sanity Block Content to HTML with Anchor Tags for JSON-LD

1 replies
Last updated: Jul 8, 2021
Hi - trying to generate rich results using JSON-LD. The problem I'm facing is that the content from the CMS comes in Block format. I would need to parse it to HTML (no need for classnames). Most importantly I need to keep anchor tags in the parsed result. I see
block-content-to-html
does that but examples are limited. Anyone with experience on this?
AI Update

Based on the documentation, here's how to convert Sanity block content to HTML while preserving anchor tags:

Use @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>`
      }
    }
  }
})

Key Points

  • Links are preserved automatically as long as you don't override the default serializers
  • Use the marks component to customize how link annotations are rendered
  • The library handles standard HTML output without classnames by default
  • For JSON-LD FAQPage rich results, the plain HTML output (including anchor tags) works perfectly with Google's requirements

Check out the full documentation on presenting Portable Text for more examples and the @portabletext/to-html GitHub repo for detailed usage.

Show original thread
1 reply
Solved. I thought I needed to add regular html tags to the serializer but it's handled automatically.

Sanity – Build the way you think, not the way your CMS thinks

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.

Was this answer helpful?