Syntax Highlighting
Author Cloudapp
E.G.

Next.js 14 - Advanced Syntax / Code Highlighting

July 10, 2024
Table of Contents

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.

  1. New Import on line 3

    “import {transformerNotationHighlight } from @shikijs/transformers;”

  2. 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:

Please consider clapping and following the writer! 👏 on our Medium Account

Or follow us on twitter -> Cloudapp.dev

Related articles