Home Blog Front End Development

Adding Code Syntax Highlighting to React Markdown - Gatsby/Strapi

Adding code syntax highlighting to react-markdown....

By John Phung

2020-10-15

When I created this website using Strapi and the CMS, despite having a powerful rich text editor, the markdown aspect does not include code syntax highlighting.

If you have built your website using react under the hood, here's how you can easily add syntax highlighting for your blog posts.

We need the react-markdown package (which you should have already installed to display the html content from Strapi) and we also need react-syntax-highlighter package.

1npm install react-syntax-highlighter react-markdown

Next, let's create the code block (CodeBlock.tsx) that will format the markdown pre tags according to the specified code language. You can visit thereact-syntax-highlighter) github to see supported language and other config options.

1import React from "react"
2import { Prism as SyntaxHighlighter } from "react-syntax-highlighter"
3import { materialDark } from "react-syntax-highlighter/dist/esm/styles/prism"
4
5type Props = {
6  language: string
7  value: string
8}
9
10const CodeBlock: React.FC<Props> = ({ language, value }) => {
11  return (
12    <SyntaxHighlighter
13      language={language}
14      style={materialDark}
15      customStyle={preStyles}
16      wrapLines={true}
17      showLineNumbers
18    >
19      {value}
20    </SyntaxHighlighter>
21  )
22}
23
24const preStyles = {
25  fontSize: "0.8rem",
26}
27
28export default CodeBlock

Now we have the code block component, we need to import into our blog post or any other components which will use it for syntax highlighting.

To display rich text content in the react application, we simpy just pass the queried content into a React-Markdown component that is imported from the library. So for example, here's how my blog-post template looks like.

1import React from "react"
2import { Link, graphql } from "gatsby"
3import Img, { FluidObject } from "gatsby-image"
4import Layout from "../components/layout"
5import ReactMarkdown from "react-markdown"
6import CodeBlock from "../components/CodeBlock" // react syntax component 
7
8interface Props {
9  data: Data
10  pageContext: PageContextData
11}
12
13interface PageContextData {
14  id: string
15  prevPost: {
16    title: string
17    path: string
18  }
19  nextPost: {
20    title: string
21    path: string
22  }
23}
24
25interface Data {
26  strapiArticle: {
27    title: string
28    content: string
29    strapiId: string
30    published_at: string
31    image: {
32      childImageSharp: {
33        fluid: FluidObject
34      }
35    }
36    slug: string
37    category: {
38      name: string
39    }
40    author: {
41      name: string
42    }
43    excerpt: string
44  }
45}
46
47export const query = graphql`
48  query ArticleQuery($id: String!) {
49    strapiArticle(strapiId: { eq: $id }) {
50      title
51      content
52      published_at
53      image {
54        childImageSharp {
55          fluid {
56            ...GatsbyImageSharpFluid
57          }
58        }
59      }
60      slug
61      category {
62        name
63      }
64      author {
65        name
66      }
67      excerpt
68    }
69  }
70`
71
72const Blog: React.FC<Props> = ({ data, pageContext }) => {
73  const article = data.strapiArticle
74  return (
75    <Layout>
76     // ... div's and stuff
77
78      <div className="py-12 font-mont text-lg float-right w-full font-medium">
79          <ReactMarkdown
80            source={article.content}
81            renderers={{ code: CodeBlock }}   // set renderer option code to CodeBlock component 
82          />
83        </div>
84
85    // ...other divs and stuff
86
87    </Layout>
88  )
89}
90
91export default Blog

Also for those unaware of how the markdown format should be created in the rich text editor, this link shows a comprehensive set of examples.