The Needs
There are blogs, websites, and online documents that have their code block with some lines highlighted. As in the screenshot below.
I always want to implement this cool thing for my own blog which is made of Next.js and MDX. I use Prism.js for highlighting the syntax of the code block. However, I couldn't find a way to enable its Line Highlight plugin.
The Flawed Way
My old approach was calling Prism in useEffect
:
// This is the blog post layout component
import Prism from "prismjs";
const BlogPost = (props) => {
useEffect(() => {
if (typeof window !== "undefined") {
Prism.highlightAll()
}
}, []);
return (
// omitted
)
}
This approach cannot implement line highlight (at least not that I am aware of).
The Right Way
After a VERY LONG time of research, I finally discovered a solution: instead of using prismjs
with next-mdx-remote
, we can use rehype-prism-plus with next-mdx-remote
.
As the next-mdx-remote
official document says when we serialize the MDX content, we can use remarkPlugins
and rehypePlugins
. rehype-prism-plus
is one of the "rehypePlugins".
So with putting rehypePrism
in that rehypePlugins
array, we can use rehypePrism
just like it should be and without any additional configurations. The code is something like this:
// This is the UPDATED blog post layout component
import { serialize } from 'next-mdx-remote/serialize';
import rehypePrism from 'rehype-prism-plus';
const BlogPost = (props) => {
// omitted
};
export const getStaticProps = async ({ params }) => {
const content = {
// omitted, not really like this
};
const mdxSource = await serialize(content, {
mdxOptions: {
remarkPlugins: [],
rehypePlugins: [rehypePrism],
},
});
return {
// omitted
};
};
Here is the whole code of this blog post page.
With this setup, if we inspect the code block with the Chrome dev tool, we can see that line 2 and line 16 have an extra class highlight-line
(as seen in the screenshot above). Make sure the stylesheet for code block has highlight-inline
style defined.
code[class*='language-'] .highlight-line {
background-color: hsl(256deg 100% 96%);
display: block;
}
I import this stylesheet in the _app.tsx
file to make it use globally.