Render Code Snippets with Gatsbyjs and Contentful

November 14, 2023
In this post, I'll go into how to pull a code snippet from Contentful and render it within GatsbyJS with syntax highlighting. No need for any apps or UI extensions!

Pulling in code snippets from Contentful and getting everything looking good takes a few steps.

But first, let's start with Contentful.

You will want to create a long text field within Contentful for a model. Once the model is created, create whatever you content you want that uses this model. In your long-text field, wrap your code snippet with three back-ticks on the top and bottom. It should look like the following.

Using the GraphQL explorer that comes with Gatsby, you can then execute the correct query to acquire the raw snippet data. Right now the Snippet is in a markdown format from Contentful. I like to use the Markdown-It library which will render out the data we received from the Contentful GraphQL query.

Let's create a React component called Snippet.

snippet.jsx
import React from 'react';
import MarkdownIt from 'markdown-it/lib';

const md = new MarkdownIt({
    html: true,
    linkify: false,
});

const Snippet = ({ markdown, filename }) => {
    return (
        <div>
            <div dangerouslySetInnerHTML={{__html: md.render(markdown)}}></div>
        </div>
    )
}

Now let's import in the highlight.js library for all our syntax highlighting goodness.

page.jsx
import React, { useEffect } from 'react';
import Snippet from '../components/snippet';
import hljs from 'highlight.js/lib/core';
import html from 'highlight.js/lib/languages/xml';
import js from 'highlight.js/lib/languages/javascript';
import css from 'highlight.js/lib/languages/css';

const Blog = (data) => {
      useEffect(() => {
        hljs.registerLanguage('xml', html);
        hljs.registerLanguage('javascript', js);
        hljs.registerLanguage('css', css);
        hljs.configure({ ignoreUnescapedHTML: true});
        hljs.highlightAll();
    }, []);

    return (
      <Snippet markdown={data.markdown} />
    );
}

This will apply highlighting to our new markdown. You can import more classes for whatever programming language you're using. In this case I'm just importing js,css, and html.

Lastly, you will need to pick a theme to apply styling to the snippet. There's a bunch of prebuilt themes that can be found in this Github repository.

And that's it. You should be able to pull in data from Contentful, convert it to markdown and apply all the highlighting and goodness you need to get it to render out.

If you're rendering out snippets within a rich text editor in Contentful, you will probably have to leverage the Contentful API, especially the options to streamline development.

page.jsx
import { renderRichText } from 'gatsby-source-contentful/rich-text';

const options = {
    renderNode: {
        [BLOCKS.EMBEDDED_ENTRY] : function(node, children) {
                // return your component here 
        },
}

//later on in your component's render
 { renderRichText(richTextData, options)}