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.