Dramatic Development

Adding A Custom Synthax Theme To Your Blog Using Prism-React-Renderer

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.

Prerequisites

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.

Changing the default theme

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>
)
}

Adding a custom theme

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.js
import 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.js
const 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.

Congrats!

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,