How to Add Syntax Highlighting to the "Sanity-Gatsby-Blog" Starter

January 13th, 2020

Adding in proper syntax highlighting was the next order of business for me after I implemented markdown support for my new sanity-gatsby-blog project. (And for reference, I also wrote out the process for adding markdown support in my first post to it!)

The process for this was relatively straightforward from the documentation I found. For proper code blocks, the react-syntax-highlighter package (link) fit nicely into my project.

What wasn't clear to me at the start was that I'd have to style my own HTML <code> tags by hand. I thought react-syntax-highlighter would automagically inject the CSS I needed, but I was wrong. Instead, it allowed me to specify a component of my choice to handle inline code.

Instructions

If you're using these instructions in sanity-gatsby-blog, everything here takes place in the web/ directory.

  1. Run npm install react-syntax-highlighter
  2. Create src/components/code-block.js
import React, { PureComponent } from 'react'
import PropTypes from 'prop-types'
import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter'
import { xonokai } from 'react-syntax-highlighter/dist/esm/styles/prism'

class CodeBlock extends PureComponent {
  render() {
    const { language, value } = this.props
    return (
      <SyntaxHighlighter language={language} style={xonokai}>
        {value}
      </SyntaxHighlighter>
    )
  }
}

CodeBlock.propTypes = {
  value: PropTypes.string.isRequired,
  language: PropTypes.string
}

CodeBlock.defaultProps = {
  language: null,
}

export default CodeBlock
  1. Create src/code/inline-code.js
import React, { PureComponent } from 'react'
import PropTypes from 'prop-types'

const codeStyles = {
  fontFamily: '"Inconsolata", monospace',
  margin: '3px',
  padding: '1px 6px',
  backgroundColor: '#f7f7f7',
  border: '1px solid #ededed',
  borderRadius: '5px',
}

class InlineCode extends PureComponent {
  render() {
    const { value } = this.props
    return (
      <code style={codeStyles}>
        {value}
      </code>
    )
  }
}

InlineCode.propTypes = {
  value: PropTypes.string.isRequired,
}

export default InlineCode
  1. In src/components/blog-post.js, import CodeBlock and InlineCode
  2. Add a renderers prop to the <ReactMarkdown /> component
{body && <ReactMarkdown source={body} renderers={{ code: CodeBlock, inlineCode: InlineCode }} />}