Table of Contents
- Why Shiki?
- Used Stack
- Inspiration and initial source
- Two new NPM Packages
- New Component for Syntax Highlighting
- Component Integration into the page.tsx
- Let’s make it nice
- Passing Props in Page.tsx
- First nice, now we enhance it
- Highlighting Specific Lines
- Adapting code Prop on Page.tsx
- Showing Code Changes
- New Classes “diff remove” and “diff add”
- Including Filenames and additional styling
- Integration of Line Numbers with TailwindCss
- Styling Highlights and Diffs
- Adapting post.config.js
- Final Result
- Cloudapp-dev, and before you leave us
You can use different approaches to integrate code blocks on your blog or website (TailwindCSS, etc.). I came across a modern approach to syntax highlighting and discovered Shiki, a relatively new syntax highlighter developed by Pine Wu and maintained by Anthony Fu. Significant companies like Vercel utilize Shiki for their Next.js documentation and Astro for syntax highlighting.
Here is the GitHub repo with the entire code. Below, you will find the link to the example page.
Example page hosted on Vercel -> https://nextjs14-contentful-syntax-highlighting.vercel.app/
Why Shiki?
Syntax highlighting in Next.js apps can be a smart move. Shiki is based on TextMate grammar, the same system used by Visual Studio Code, ensuring accurate and visually appealing code highlighting. More importantly, for the performance of our website, Shiki renders highlighted code ahead of time. This means no extra JavaScript is shipped to the client for syntax highlighting, aligning with Next.js's push for server components and minimal client-side JavaScript.
Used Stack
I will start with my default stack:
Next.js 14 as the web framework, and I will use the provided middleware edge function
NPM Package Shiki for syntax highlighting and the corresponding transformers package
Vercel for hosting
Inspiration and initial source
Thanks to Nikolai Lehbrink for the inspiration and the initial code source, which I used to integrate into my Next.js 14 project. If you are interested in a detailed how-to regarding the integration in Next.js 13 -> https://www.nikolailehbr.ink/blog/syntax-highlighting-shiki-next-js
Two new NPM Packages
New Component for Syntax Highlighting
Now, I will create a new component to reuse in the home.
Component Integration into the page.tsx
Below is the integration into the page.tsx
Let’s make it nice
Right now, everything is hard-coded, so let’s extend our component to take the code, the language (lang) and the theme as props.
Passing Props in Page.tsx
First nice, now we enhance it
The basic functionality is done. Let’s add some enhancements to our code block.
Highlighting Specific Lines
I didn’t want to miss out on the implementation of line highlighting. Shiki has a few transformers That let us quickly set this up.
I have already installed the transformers package and the base Shiki package.
New Import on line 3
“import {transformerNotationHighlight } from @shikijs/transformers;”
Transformers activation below “lang” and “theme”
transformers: [transformerNotationHighlight()],
Adapting code Prop on Page.tsx
I added this part “ // [!code highlight]” at the end of the “code” line.
This adds the “has-highlighted” class to the <pre> and the “highlighted” class to the <span>. Now, I target the class with CSS and style it accordingly. I will use TailwindCSS (with its arbitrary values).
Showing Code Changes
To add classes for added and removed lines, we follow the same steps as above, but with a different transformer called transformerNotationDiff. First, imported the new transformer, and then I add the // [!code ++] comment for added lines and a respective // [!code --] comment for removed lines to your code prop.
New Classes “diff remove” and “diff add”
This again adds the and We can use classes on the rendered HTML to style the component later.Including Filenames and additional styling
Besides the highlighting, I wanted to add filenames to my code components. That way, the reader always knows to which file the given code belongs.
So, let’s add a prop to our component and some initial styling to see the effect.In our let's add filenames by passing a name to the prop.<Code code="let a = 1 + 4" filename="index.js" />
Integration of Line Numbers with TailwindCss
One common thing to integrate in a code block are line numbers, making the component visually more appealing while also giving the reader a reference for specific lines in the code.
Styling Highlights and Diffs
In order to enhance the design of the individual highlighted lines, I added the following styles as well.
Adapting post.config.js
You don’t have to install the plugin, as it is packed with TailwindCSS, which was already installed.
Final Result
Lastly, I added some styles to make the whole syntax highlight component more visually appealing and added a background gradient. I added a copy-to-clipboard function as well. You will find the complete code at the top of this story on the provided link.
Cloudapp-dev, and before you leave us
Thank you for reading until the end. Before you go: