Syntax Highlighting with MDX in Next.js
If you write about programming, devops, machine learning, data journalism and lots of other stuff that need any kind of code in the content, I would suggest adding syntax highlighting to your articles to make things a little clearer.
I just re-launched this blog with Next.js and MDX for content and I needed a plugin to highlight syntax in code blocks (because apparently I have those a lot) and I found a post by Colin that really helped to get things going. However, apparently languages like Elixir and nginx configs are not included by default, so I needed a little more config.
Enabling Syntax Highlighting in MDX
The code below is in my [slug].js
file, which displays a single post.
<article className="post">
<PostsMeta thumbnailURL={thumbnailURL} title={title} slug={slug} description={description} />
<FeaturedImage thumbnailURL={thumbnailURL} />
<h1>{title}</h1>
<MDXRemote {...mdxSource} />
</article>
The mdxSource
is our main content, which we need to pass to the syntax highlight plugin like rehype-highlight
Add Missing Language to Rehype Highlight
We're both going to import some additional languages and define an alias, because there is a 0 percent change I will ever get right if it's docker
or dockerfile
when defining a code block, so both '```docker'
and '```dockerfile'
will both work.
import rehypeHighlight from "rehype-highlight";
import langNginx from 'highlight.js/lib/languages/nginx'
import langElixir from 'highlight.js/lib/languages/elixir'
import langDockerfile from 'highlight.js/lib/languages/dockerfile'
import 'highlight.js/styles/a11y-dark.css'
const languages = {
nginx: langNginx,
elixir: langElixir,
dockerfile: langDockerfile
}
const aliases = { dockerfile: 'docker' }
// ...
const mdxSource = await serialize(content, {
mdxOptions: {
rehypePlugins: [[rehypeHighlight, {
ignoreMissing: true,
languages,
aliases
}]]
},
});
lastly we're passing the plugin to rehypePlugins
. Note that this is an array and just like with webpack plugins the second index has the options, in this case: { ignoreMissing: true, languages, aliases }
. If you don't set ignoreMissing
your compilation might fail.
This is what the error message looks like when building with next.js:
Error occurred prerendering page "/p/deploying-a-vue-js-single-page-app-including-router-with-docker". Read more: https://nextjs.org/docs/messages/prerender-error
Error: [next-mdx-remote] error compiling MDX:
Unknown language: `docker` is not registered
37 |
38 | <strong>Dockerfile</strong>
> 39 | ```docker
| ^
40 | # Create the container from the alpine linux image
41 | FROM alpine:3.7
These errors will also occur if your code should start directly after the backticks. You can see a full list of supported languages here: highlight js languages.
There is some support for jsx
in highlight.js at the moment, for full support you can check out rehype-prism