How I Implemented Syntax Highlighting in the Kodikion. Next.js Blog
A walkthrough of adding syntax-highlighted code blocks to the Kodikion. Next.js application.
Note: This walkthrough was originally written for the Next.js version of the Kodikion blog, which has since been discontinued.
This is going to be a pretty straight-forward post—almost micro-blog short. Essentially, I wanted to add syntax highlighted code blocks. In this Next.js template, the codeblocks came pretty bare. There were no borders and the code would add an awkward horizontal scroll to the page. Also, there was no syntax highlighting, so it was just a wave of black text.
I added the following to get started:
yarn add rehype-highlight
yarn add highlight.js
yarn add rehype-stringify
yarn add remark-gfm
yarn add remark-rehype
I updated my src/lib/markdownToHtml.ts
file to incorporate these packages. Originally, it was just five lines:
// filelocation: src/lib/markdownToHtml.ts
import { remark } from "remark";
import html from "remark-html";
export default async function markdownToHtml(markdown: string) {
const result = await remark().use(html).process(markdown);
return result.toString();
}
The single remark-html
plugin turned my markdown blog posts in to HTML, but it left the code blocks monochrome and with no other styling other than monospace fonts.
I rebuilt the helper as a remark -> rehype pipeline so that I can get syntax colors and even more extra features in the future (GitHub style tables).
// filelocation: src/lib/markdownToHtml.ts
import { unified } from "unified";
import remarkParse from "remark-parse";
import remarkGfm from "remark-gfm";
import remarkRehype from "remark-rehype";
import rehypeHighlight from "rehype-highlight";
import rehypeStringify from "rehype-stringify";
export default async function markdownToHtml(markdown: string) {
const html = await unified()
.use(remarkParse) // Markdown ➜ mdast
.use(remarkGfm) // GitHub goodies
.use(remarkRehype) // mdast ➜ hast
.use(rehypeHighlight) // colour every token
.use(rehypeStringify) // hast ➜ HTML string
.process(markdown);
return String(html);
}
In my src/app/globals.css
file, I imported Highlight.js
. This .js
file gives me 40+ themes to choose from—I opted for Visual Studio Code 2015 dark-dimmed.
/* filelocation: src/app/globals.css */
@import 'highlight.js/styles/vs2015.css';
@tailwind base;
@tailwind components;
@tailwind utilities;
I did some polishing in the <pre>
tag as well:
/* filelocation: src/app/globals.css */
pre {
background: #0d1117;
color: #c9d1d9;
font-family: ui-monospace, SFMono-Regular, Consolas, Menlo, monospace;
font-size: .875rem;
padding: 1rem 1.25rem;
border-radius: .5rem;
overflow-x: auto;
}
pre code { display: grid; }
I thought about switching over to rehype-pretty-code
, but maybe another time as this suits my needs for right now.