The Best Way To Use Prism.js Highlighting With Nextjs
Prism is an awesome and easy library to use to get awesome code snippet highlighting in your blog posts. When figuring out how to use it with next js, you have 2 primary options to get code highlighting with Prism.
The first option is to use Prism on the front end and use js to parse and add highlighting to your code on the browser. Here is a great article explaining how to do this in detail. It walks the user through prism, and setting it up in your front end.
However, if you are pre-rendering your site, there is a better alternative. Specifically we are going to be looking at using data coming from a ghost blog, as this is how this site is generated. We can get rid of the useEffect
Prism call in the front end code, and move all the highlighting work to build time!
Let's code through it.
First let's add dependencies:
yarn add prismjs cheerio html-entities
Then whatever page you want to load the highlighted code snippets on, get into your getStaticProps
function.
import Prism from 'prism';
import loadLanguages from 'prismjs/components/index';
import cheerio from 'cheerio';
import { decode } from 'html-entities';
export async function getStaticProps({ params: { slug } }) {
const post = await api.posts.read({ slug });
// properly parse and format all hightlighted
// code blocks on the server
const $ = cheerio.load(post.html);
const $codes = $('code[class^=language]');
if ($codes.length > 0)
$codes.each(function () {
const $code = $(this);
const lang = $code.attr('class').replace('language-', '');
const code = decode($code.html());
// default loaded languages with prisma, skip to decrease build times
if (!['javascript', 'css', 'clike', 'markup'].includes(lang))
loadLanguages([lang]);
$code.html(Prism.highlight(code, Prism.languages[lang], code));
$code.parent('pre').addClass(`language-${lang}`);
post.html = $.html();
});
return {
props: post,
revalidate: 1
};
}
The above code works by first sourcing the content from somewhere. This doesn't have to be a ghost blog, it can be anywhere that you get your content from. The only thing you have to ensure is that your content has properly formed html code blocks that look like:
<pre>
<code class="language-javascript">
</code>
</pre>
Next we use cheerio to grab the specific code related html from the code blocks. Then we use Prism to transform the code blocks into proper html with all the highlighting classes added!
One this is completed, we further clean out the html by decoding any html entities and now our code blocks are ready to be properly built in our pre-rendered blog posts.
As long as we have the prism css in our front end bundle, we don't have to use any JavaScript on the front end to get beautiful code highlighting. This creates the most performant front end experience by allowing us to load less dependencies and run less JS in the front end!