July 03, 2020
This week, I decided to finally build a new blog. Previously, I had been publishing on medium and dev, but I figured it was time to create a centralized place for all my posts to live. I knew that I wanted to have support for MDX, and I had a great experince using Gatsby to build my personal site, so I decided to use the Gatsby Starter Blog MDX template. I knew I was going to use a custom color shceme for the blog, and I so of course I needed a synthax theme to match! In this post, I will walk you through created a custom synthax theme for a blog using prism-react-renderer.
This guide will assume that you already have prism-react-rendering set up in your blog. If you do not, I would reccomend following the intallation instructions in the docs. You can also check out this guide about migrating from gatsby-remark-prismjs to prism-react-renderer by Prince Wilson.
If you simply want to chnage your synthax theme to one of the commonly used, prism-react-renderer ships with a bunch out of the box. The default is duotone dark, but there are also some classics such as dracula and nightowl. You can find a full list here.
To switch themes, you need to import it and then pass it as the value for the theme prop in the Highlight
component.
import React from 'react'import Highlight, { defaultProps } from 'prism-react-renderer'import dracula from 'prism-react-renderer/themes/dracula'export const Code = ({ codeString, language, ...props }) => {return (<div className='code'><Highlight{...defaultProps}code={codeString}language={language}theme={dracula}>{({ className, style, tokens, getLineProps, getTokenProps }) => (<pre className={className} style={style}>{tokens.map((line, i) => (<div {...getLineProps({ line, key: i })}>{line.map((token, key) => (<span {...getTokenProps({ token, key })} />))}</div>))}</pre>)}</Highlight></div>)}
WWe are going to define our custome theme in a separate JavaScript file, and then import it just as we did in the last section. You can have this file live wherever you want, but I keep mine in a folder at src/themes
. I would reccomend modeling your JS file after one of the theme files in prism-react-renderer. The file will contain an object with two keys: plain
, which defines the standard text and background colors; styles
, where you can define colors and text styles based on individual keyword types. The dracula theme from prism-react-renderer file looks like this:
// prism-react-renderer/src/themes/dracula.jsimport type { PrismTheme } from "../types";var theme: PrismTheme = {plain: {color: "#F8F8F2",backgroundColor: "#282A36"},styles: [{types: ["prolog", "constant", "builtin"],style: {color: "rgb(189, 147, 249)"}},{types: ["inserted", "function"],style: {color: "rgb(80, 250, 123)"}},{types: ["deleted"],style: {color: "rgb(255, 85, 85)"}},{types: ["changed"],style: {color: "rgb(255, 184, 108)"}},{types: ["punctuation", "symbol"],style: {color: "rgb(248, 248, 242)"}},{types: ["string", "char", "tag", "selector"],style: {color: "rgb(255, 121, 198)"}},{types: ["keyword", "variable"],style: {color: "rgb(189, 147, 249)",fontStyle: "italic"}},{types: ["comment"],style: {color: "rgb(98, 114, 164)"}},{types: ["attr-name"],style: {color: "rgb(241, 250, 140)"}}]};export default theme;
To modify this file, I am first going to remove the types since I am not using TypeScript. Then, I will define a set of color variables at the top of the file.
// src/themes/1976.jsconst darkBrown= '#744f25'const brown = '#2b1d0e'const yellow = '#f1d248'const orange = '#fe8c1b'const red = '#fb4f28'const teal = '#8ff0e0'const cream = '#fffbf1'const theme = {// ...}
Now, time for the fun part! Experiment with which colors you want to assign to the different keywords. My configuration is tsill a work in progress, but currently looks like this:
const darkBrown = '#744f25'const brown = '#2b1d0e'const yellow = '#f1d248'const orange = '#fe8c1b'const red = '#fb4f28'const teal = '#8ff0e0'const cream = '#fffbf1'const theme = {plain: {color: cream,backgroundColor: brown},styles: [{types: ["prolog", "constant", "builtin", "important", "deleted", "type", "attr-name"],style: {color: red}},{types: ["inserted", "function"],style: {color: yellow}},{types: ["changed"],style: {color: yellow}},{types: ["punctuation", "symbol"],style: {color: teal}},{types: ["string", "char", "selector"],style: {color: teal}},{types: ["keyword", "variable", "boolean", "number"],style: {color: orange,fontStyle: "italic"}},{types: ["comment"],style: {color: darkBrown}},{types: ["tag"],style: {color: yellow}}]};export default theme;
Notice how you can set some keywords to be italic with the fontStyle
attribute in the style
object.
Once you are done with your theme, you just need to import it and then pass it as the value for the theme prop in the Highlight
component, as we did when changing the default theme.
You can now make a custome synthax theme for your code symples using prism-react-renderer. Thank you so much for reading, and best of luck with your themes!
The personal blog of Shane Lonergan. NYC based software engineer, actor, director, and musician. Documenting my journey from the stage to the computer screen. To keep up to date, you should follow me on Twitter.