
How to use Shiki 式 Syntax highlighter with Next.js and Tailwind CSS
Set Up Your Next.js Project
First things first—if you don’t have a Next.js project yet, start with a bit of magic:
Answer a few bootstrap questions.
And voilà! You've got a fresh new project, ready to be enhanced with a awesome CodeBlock
component.
Download Your Favorite VS Code Theme Files
Go into your VS Code editor and find your favorite theme. A big shout-out to the creator of the Pace Theme for that awesome style!
Next, copy your theme files in json
format into your Next.js project, maybe in lib/themes
.
For a clean structure, place them in a dedicated folder. Here’s an example for a dual theme setup:
./lib/themes/dark.json
and ./lib/themes/light.json
Install Shiki
Create the highlightCode
Function
Now for the real deal: let’s write a highlightCode
function that will turn your code into a work of art. Add this gem:
Create a Server Component to Inject Styled Code
Now, let's create a component that will allow us to inject all this stylish code right into our page! Create code-block.tsx
in your components
folder:
Create a Client-Side Wrapper for Top-Notch Style
Let’s add a client wrapper to bring your code block to life with a copy option, scrolling, and a few other neat extras. Here’s the CodeBlockWrapper
component:
Configure Dark and Light Themes for Shiki
Before using our CodeBlockWrapper
component, we need to add a little CSS so that the dark and light themes automatically adjust.
Add this code to your global CSS file:
Use the Component and Admire the Results
Finally, it’s showtime! Call CodeBlockWrapper
in your component, pass in your code, and enjoy the view:
P.S.: All the code blocks on my portfolio are generated like this! Not too shabby, right?
And that’s it! Your code is now ready to shine with Shiki, and in the theme of your choice. 🎉
If you want to dive deeper into the code, check out the repo from my portfolio, where I walk through exactly how it’s done: components/utils/code-block-wrapper.tsx