Syntax Highlight Codes on your Ghost CMS Powered Gatsby Blog with PrismJS

Syntax Highlight Codes on your Ghost CMS Powered Gatsby Blog with PrismJS

"This post will walk you through how to set up code syntax highlighting using PrismJS on a Ghost CMS backed Gatsby blog."


This guide was written based on:

  • Gatsby Ghost Blog build on top of gatsby-starter-ghost version 1.0.0

with these dependencies (partial):

"@tryghost/helpers": "1.1.22",
"@tryghost/helpers-gatsby": "1.0.25",
"gatsby": "2.19.23",
"gatsby-rehype-prismjs": "^1.1.2",
"gatsby-source-filesystem": "2.1.48",
"gatsby-source-ghost": "4.0.4",
"gatsby-transformer-rehype": "^1.7.3",
"prismjs": "^1.20.0",
"react": "16.13.0",

1. Install Require Packages

First, we need to install the required packages. They are:

  • gatsby-transformer-rehype
  • gatsby-rehype-prismjs

Install them using:

yarn add gatsby-transformer-rehype gatsby-rehype-prismjs

or

npm install --save gatsby-transformer-rehype gatsby-rehype-prismjs

2. Configure gatsby-config.js

Next, we need to configure and add these new plugins to gatsby-config.js so that Gatsby is aware and make use of them.

module.exports = {
    //...
    plugins: [
        // ...
        
        // 1. - Add transformer for HTML sources.
        {
            resolve: `gatsby-transformer-rehype`,
            options: {
                // 2. - Ensure these only apply to type
                filter: (node) =>
                    node.internal.type === `GhostPost` ||
                    node.internal.type === `GhostPage`,
                plugins: [
                    {
                        // 3. - Add syntax highlight for code block.
                        resolve: `gatsby-rehype-prismjs`,
                    },
                ],
            },
        }
    ]
}

3. Configure Query

fragment.js

The two plugins will now parse our HTML and add

childHtmlRehype {
	html
}

to our GhostPost and GhostPage GraphQL.

To make Gatsby aware of these new properties, we need to add it to our fragments definition.

In our ./src/utils/fragments.js file, find the line defining fragment GhostPostFields on GhostPost and add the above childHtmlRehype to it.

It should look something like:

// Used for single posts
export const ghostPostFields = graphql`
    fragment GhostPostFields on GhostPost {

        # ...

		# Content
        plaintext
        html
        childHtmlRehype {            html        }		
		# ...

	}
`;

You can do the same for GhostPage.

post.js

Now that Gatsby are aware of the transformed HTML, we need to switch our post.js to use this newly added properties instead of the normal html.

In ./src/templates/post.js, apply following edit:

Post.propTypes = {
    data: PropTypes.shape({
        ghostPost: PropTypes.shape({
            codeinjection_styles: PropTypes.object,
            title: PropTypes.string.isRequired,
            html: PropTypes.string.isRequired,
            childHtmlRehype: PropTypes.shape({                html: PropTypes.string.isRequired,            }),            feature_image: PropTypes.string,
            primary_author: PropTypes.shape({
                name: PropTypes.string.isRequired,
                profile_image: PropTypes.string,
                slug: PropTypes.string.isRequired,
            }).isRequired,
        }).isRequired,
    }).isRequired,
    location: PropTypes.object.isRequired,
};

Now, replace all post.html in your JSX with post.childHtmlRehype.html.

{/* The main post content */}
<section
    className="content-body load-external-scripts"
    dangerouslySetInnerHTML={{
    	__html: post.childHtmlRehype.html,    }}
/>

page.js

Repeat the same steps as post.js above.

4. Select Theme

Now you can select which CSS theme to use. Go to your gatsby-browser.js and add the following require:

// gatsby-browser.js
require("prismjs/themes/prism-solarizedlight.css")

You can find all the default themes that ship with PrismJS here. Visit their official website for theme preview.

Finally, restart your Gatsby Development server and enjoy beautifully highlighted and clean looking code! Don't forget to write and share more content to the world!!! :)


Written by Romson Preechawit

Hi there! I'm a typical geek, designer, developer. Love coding, design, photography, reading, and a lot more. English is not my first language so please help correct my grammar! :)

Romson Preechawit