1

I'm using Prismic CMS and Gatsby (both latest version) and the officical gatsby-source-prismic plugin.

I'm trying to fetch blog posts from Prismic and display them on my blogpage which works fine.
The only thing I struggle is the HTML Serializer at v3-plugin.

I used this template https://github.com/LekoArts/gatsby-starter-prismic-i18n as my starter.- As this git is based on v2, I had to rewrite almost everything to adjust it to v3.

My "Code-Block" Slice just outputs me preformatted HTML (after Prism Syntax Highlight) which is wrong:
This is my Output:
enter image description here

my Code Component:

const CodeBlock = ({ input }) => {
  return (
    <>
      //this was for v2
      <Content dangerouslySetInnerHTML={{ __html: input.primary.code_block.html }} />
      //this should be for v3
      <RichText render={input.primary.code_block.raw} htmlSerializer={htmlSerializer} />
    </>
  )
}  

my htmlSerializer:

    import React from 'react'
import { Elements } from 'prismic-richtext'
import Prism from 'prismjs'

const propsWithUniqueKey = function (props, key) {
  return Object.assign(props || {}, { key })
}

// Labels with this name will be inline code
const codeInline = ['text']
// Labels with these names will become code blocks
const codeBlock = ['javascript', 'css', 'scss', 'jsx', 'bash', 'json', 'diff', 'markdown', 'graphql']

const htmlSerializer = (type, element, content, children, index) => {
  var props = {}

  switch (type) {
    // First differentiate between a label and a preformatted field (e.g. the Code Block slice)
    case Elements.label: {
      // Use the inline code for labels that are in the array of "codeInline"
      if (codeInline.includes(element.data.label)) {
        return `<code class="language-${element.data.label}">${content}</code>`
      }
      // Use the blockquote for labels with the name "quote"
      if (element.data.label === 'quote') {
        return `<blockquote><p>${content}</p></blockquote>`
      }
      // Use the code block for labels that are in the array of "codeBlock"
      // Choose the right PrismJS highlighting with the label name
      if (codeBlock.includes(element.data.label)) {
        return `<pre class="language-${element.data.label}"><code class="language-${element.data.label
          }">${Prism.highlight(content, Prism.languages[element.label])}</code></pre>`
      }
      return null
    }
    case Elements.preformatted: {
      props = { className: `language--${element.label}` }

      if (codeBlock.includes(element.label)) {

        const text = Prism.highlight(
          element.text,
          Prism.languages[element.label]
        );
        return React.createElement('div', {}, `<pre class="language-${element.label}"><code class="language-${element.label}">${Prism.highlight(
          element.text,
          Prism.languages[element.label]
        )}</code></pre>`)

        // my other try
        return React.createElement('pre', { className: `language-${element.label}` },
          React.createElement('code', { className: `language-${element.label}` }, text))

      }
      return null
    }
    default: {
      return null
    }
  }
}

export default htmlSerializer  

In v3 I get an error when I try to add the serializer to my gatsby-config.js .

My "version" outpuits at least the pre and code-tags but the prism-highlighter outputs just HTML. The RichText.render method doesn't work as intended, as it seems or I got a logic error in my serializer.

Marek123
  • 1,193
  • 7
  • 35
  • 75

1 Answers1

0

Maybe it's not the built-in/ideal solution but it will certainly work, using markdown-to-jsx dependency.

<Markdown>input.primary.code_block.html</Markdown>

Additionally, using your approach you can try:

  <RichText render={input.primary.code_block.html} htmlSerializer={htmlSerializer} />
Ferran Buireu
  • 28,630
  • 6
  • 39
  • 67