Syntax highlight with Shiki and Adding Copy Functionality to Codeblocks
Recently, I decided to add a code snippets section to my website. I realized two key features would greatly improve the user experience:
Better syntax highlighting
A copy code block button
Let's walk through how to implement these features step by step.
Implementing Syntax Highlighting
First, let's look at our current setup. We're using MDX with next-mdx-remote to render our content. Here's the basic structure of our MDX processing:
This code reads the content file, processes it with various plugins, and prepares it for rendering. The key plugin for our syntax highlighting is rehypePrettyCode. rehype-pretty-code is a Rehype plugin powered by the shiki syntax highlighter that provides beautiful code blocks for Markdown or MDX. It works on both the server at build-time (avoiding runtime syntax highlighting) and on the client for dynamic highlighting.
To use a specific theme, we can configure shikiOptions like this:
Now that we have syntax highlighting working, let's add a copy button to our code blocks. Instead of creating a new custom component for each code block in our MDX files, we'll modify how the code blocks are rendered on the UI.
Here's how a code block typically looks in the DOM:
We'll create a custom Figure component that will be used by MDXRemote to render these elements. This approach doesn't require importing the component in each MDX file.
This component does the following:
Finds the figcaption and pre elements among its children
Implements a handleCopyClick function to copy the code content
Renders a custom FigureCaption component with the copy button