Hi there!
I'm Arisa, a DevRel from this June living in Germany🇩🇪 (A big announcement is coming this June😏)
I have a free online programming learning community called Lilac, with free hands-on Frontend e-books👩💻
Who is this article for?
- Anyone who wants to try out integrating syntax highlight in the Storyblok blog project
 - Anyone who wants to build a tech blog with Storyblok & Gatsby.js
 - Anyone who wants to know the syntax highlight integration in a Headless CMS with Gatsby.js
 
To help you understand the prep before integrating syntax highlight in rich text from Storyblok, here are some resources to read📖
Storyblok: The Complete Guide to Build a Full-Blown Multilanguage Website with Gatsby.js
I highly recommend you to take a look at the blog post I wrote below.
This blog post requires you to have a basic understanding of the fetching rich text from Storyblok.
The blog post below helps you with hands-on source code :)
[Storyblok, Gatsby] Programmatically create blog post pages from data
  
  
  Step 1: Fetch node resolvers, NODE_CODEBLOCK with storyblok-rich-text-react-renderer
At this point, I expect you that you completed to generate a blog entry page dynamically with using gatsby-node.js file.
If you feel I started to talk about unicorns, go grab my blog post I recommended you above🦄
First things first, install storyblok-rich-text-react-renderer if you didn't have yet from the blog post I recommende you to take a look at first.
$ yarn add storyblok-rich-text-react-renderer
Import render from storyblok-rich-text-react-renderer .
If you followed the blog I asked you to take a look at first, it'll look something like this.
import { render } from 'storyblok-rich-text-react-renderer'
export default function BlogEntry({ pageContext, location }) {
  let story = pageContext.story
  story = useStoryblok(story, location)
  return (
    <Layout>
      <p>{ story.content.intro }</p>
      <div>
        {/* 👇 render a rich text data */}
        { render(story.content.long_text) }
      </div>
    </Layout>
  )
}
Technically, we already can see code_block data content type in the browser without configuring the details of code_block data content type. 
It's because long_text data content contains all rich text from Storyblok draft JSON.
code_block is a data content type to stow code blocks from Storyblok's main dashboard content input.
But it's not with styles if you see the results in the browser.
Looks treated exactly the same style as paragraph data content type.
We want our code_block data content type to be highlighted.
Step 2: Map node resolvers to custom React components
Don't be paranoid, I'll explain what's node resolvers are👍
The node resolvers are the optional second argument of the render function from storyblok-rich-text-react-renderer .
There're several values assigned from Storyblok.
render(document, {
    markResolvers: { ... }, // inline elements
    nodeResolvers: { ... }, // block elements
    blokResolvers: { ... }, // embedded components
    defaultBlokResolver: (name, props) => ( ... ),
    defaultStringResolver: (str) => ( ... ),
});
Storyblok: Storyblok Rich Text Renderer for React, README, advanced usage
We'll use nodeResolvers this time.
code_block data content type is a block element.
It's all written in the documentation.
Storyblok: Storyblok Rich Text Renderer for React, README, node resolvers
We can use below for code_block data content type.
NODE_CODEBLOCK — (children, { class }) => { ... }
Let's take a look at the example first.
import MyImage from 'components/MyImage';
import { render, NODE_IMAGE } from 'storyblok-rich-text-react-renderer';
render(document, {
    nodeResolvers: {
        [NODE_IMAGE]: (children, props) => <MyImage {...props} />
    }
});
It's nothing different from the documentation.
Just the node resolver is an image in this case.
The only differences are below.
- We don't create a separated component for 
code_blockto render - Use 
NODE_CODEBLOCK 
Based on that, we can write something like this.
import { render, NODE_CODEBLOCK } from 'storyblok-rich-text-react-renderer'
export default function BlogEntry({ pageContext, location }) {
  let story = pageContext.story
  story = useStoryblok(story, location)
  return (
    <Layout>
      <p>{ story.content.intro }</p>
      <div>
        {/* 👇 render a rich text data & code_block */}
       {
          render(story.content.long_text, {
            nodeResolvers: {
              [NODE_CODEBLOCK]: (children, story) => {
                  return (
                      <pre>
                        <code { ...story }>{ children }</code>
                      </pre>
                  )
                }
              }
            }
          )
        }
      </div>
    </Layout>
  )
}
Let me tell you the results already before you get disappointed.
It won't make any change in the browser😅
It's because we already fetched code_block when we rendered long_text data content.
If so, why we did all those work?
Trust me.
Soon later, you'll know how this way is much easier than if you try out integrating Prism.js or highlighter.js by yourself.
It's less packages to install, no babel config is required and our code is very short.
But how we'll add the syntax highlight?
We'll combine with React Syntax Highlighter.
Step 3: Apply React Syntax Highlighter
To do that, let's install it first.
$ yarn add react-syntax-highlighter
Import SyntaxHighlighter and a style theme.
import SyntaxHighlighter from "react-syntax-highlighter";
import { tomorrow } from 'react-syntax-highlighter/dist/esm/styles/prism';
You can choose your theme styles from their documentation.
The example from their documentation shows like this.
import SyntaxHighlighter from 'react-syntax-highlighter';
import { docco } from 'react-syntax-highlighter/dist/esm/styles/hljs';
const Component = () => {
  const codeString = '(num) => num + 1';
  return (
    <SyntaxHighlighter language="javascript" style={docco}>
      {codeString}
    </SyntaxHighlighter>
  );
};
It means, as long as we wrap our code elements with SyntaxHighlighter component, it might work.
It'll be like this.
return (
      <div>
        {
          render(story.content.long_text, {
            nodeResolvers: {
              [NODE_CODEBLOCK]: (children, story) => {
                  return (
                      <pre>
                        <code { ...story }>
                          <SyntaxHighlighter language={ story } style={ tomorrow }>
                            { children }
                          </SyntaxHighlighter>
                        </code>
                      </pre>
                  )
                }
              }
            }
          )
        }
      </div>
)
I recommend you to debug children and story with console.log() .
You'll see the values we want is returned.
Also, the syntax highlight theme is on🔥
In fact, NODE_CODEBLOCK returns an opject property name, class.
It means, we should be able to see that the class attribute value of "language-javascript" must be added into our code snippet HTML elements.
You mihgt face some situations with the value of undefined if you forget to choose a language when you edit your content in a main dashboard.
As long as we choose the language from our main dashboar in Storyblok, this won't happen👍
Hope you found something relevant info for your project!
              



    
Top comments (0)