Jul 1, 2024

Add Syntax Highlighting to a Next.js Blog

This site’s blog is built with Next.js. Articles are written as MDX files, i.e., Markdown plus some React components.

I created a [/posts] “Dev Notes” category to collect development memos and enabled syntax highlighting there. Notes follow.

Install

Use react-syntax-highlighter for highlighting:

Install into a Next.js project:

npm install react-syntax-highlighter --save
npm install @types/react-syntax-highlighter --dev

Setup

When using MDX with Next.js, you can customize elements via mdx-components.tsx.

Add the following:

export function useMDXComponents(components: MDXComponents): MDXComponents {
  return {
    ...components,
    pre: ({ children }) => <>{children}</>, // ②
    code: ({ className, children, ...rest }) => { // ③
      const match = /language-(\w+)/.exec(className || "");
      return match ? (
        <SyntaxHighlighter language={match[1]} style={oneDark}>
          {String(children)}
        </SyntaxHighlighter>
      ) : (
        <code {...rest} className={className}> // ④
          {children}
        </code>
      );
    },
  }
}

This highlights fenced code blocks in Markdown automatically.

Notes

  1. I’m using Prism’s oneDark style.
  2. MDX code blocks render as <pre><code>…</code></pre>, but SyntaxHighlighter generates its own pre, so we strip the outer pre to avoid nesting.
  3. If a language is present on code, render with SyntaxHighlighter.
  4. When no language is specified or for inline code, fall back to a normal code element.