Using Prism.js in a Next.js site
Prism.js is a syntax highlighter used by the Frendly blog to show styled code boxes, like this one...
If you're not using Next.js, the basic installation is to download your desired theme and languages and include the Prism.js at the end of the <body> and the Prism CSS in the HTML <head> (or use the CDN hosted files).
To have Prism style blocks of code enclose the code in <pre> and <code> tags, with a CSS class on the <code> tag for the language you want to style. Here's the list of available languages.
<code> tags into
<span> elements that it (or you!) applies styles to.
To try this basic installation in Next.js (which didn't work), I added the CSS to the
<Head> in my
<Layout> component and the Prism.js to a
<Footer> component, just before the closing
<Layout> component wraps the other page components so the
<Footer> will be on every page. You could of course have a different layout just for those pages that require the Prism functionality to save you importing it where it's not in use.
But wait, this didn't work! 😱 The styles would only show after a page refresh. This is because the Prism script is running before the DOM is available.
This calls for the React
Instead of doing the above, install the Prismjs node module in your project. (In the root of your Next.js project folder open the terminal and type...)
Now the Prism files are available to your Next.js components.
Where you want to apply Prism import it from node modules and use the React
useEffect() hook to call the Prism function
We just want
highlightAll() to run once when the component DOM is ready, so we pass an empty array
 as the second parameter to the
useEffect() hook, which is the same as the
componentDidMount() method in React class components.
Next we need the CSS so import that in
_app.js where global CSS is imported.
(I preferred to take these styles and overwrite some of them for the Frendly blog, like the background and font-size, so I've copied them to /styles/prism.css and link to that stylesheet from the next/head, as above).
If you look in the node_modules/prismjs/themes folder you'll see the themes available for import.
Now where you've used the
<code> tags with the correct language CSS class, if you load the page the styles should be applied.
Using Prism plugins and JSX styles
I'm styling JSX in some of my code blocks and for this I had to explicitly import the
I was also having a problem with the code in the
<code> block rendering as HTML. For this you can escape the HTML tags (<div>) but this is tedious.
I used the Prism Unescaped Markup plugin to handle this and simply imported it in my Layout component, and wrapped the code in comments, as per the plugin instructions.
One slight annoyance with this method, for every new line my code editor (VS Code) would remove the tab indent on any empty line, which Prism would output as a
<p> tag, messing up my code box!
To fix this I've turned off the trimAutoWhitespace in VS Code settings. On Mac, go to Code > Preferences > Settings (or type cmd + ,), search "trimAutoWhitespace" and uncheck the checkbox. Your indents should remain in place on empty lines.
If you have any questions or comments or want to connect, you can follow me on Twitter, or sign up to the newsletter in the footer for front-end articles to your inbox 👇