How to do syntax highlighting on Next.js markdown blog

Viewed 6810

I'm using Next.js for my blog and I'm storing my blogs in markdown files and converting those files to string and then into HTML using Greymatter. My code blocks break down into <pre><code class="language-whatever"> and no matter what I do, I can't get syntax highlight to occur.

I've tried adding highlight.js through npm, downloading files from highlight.js and prism, using their cdn's, and nothing is really working.

Is there anybody who has experience setting up syntax highlighting on a markdown blog using Next.js? An example or any advice would be great! Thanks.

4 Answers

I figured it out! I used react-syntax-highlighter in combination with react-markdown. I got some code snippets from this blog with how to parse the code snippets and pass then through the syntax highlighter.

Here's my repo, if you want to check out my solution.

I was using marked to convert my markdown to an HTML string which was blocking the highlighting for happening. Once I pulled my markdown content out of marked dependencies and passed in the gray-matter.content to my ReactMarkdown it worked perfectly.

...Well, maybe not perfectly...

There was some weird stuff happening when I was trying to use color themes. I ended up having the pull the theme I wanted out of the node modules and placed it in my root and called it from there and it was perfectly fine. A little hacky, but it works!

    import ReactMarkdown from "react-markdown";
    import { Content } from "mdast";
    // import light build
    import { PrismLight as SyntaxHighlighter } from "react-syntax-highlighter";
    // import only whatever languages you are using. Thaw will dramatically reduce the build size of the page
    import js from "react-syntax-highlighter/dist/cjs/languages/prism/javascript";
    import python from "react-syntax-highlighter/dist/cjs/languages/prism/python";
    // those tags are used when you write ```js  {code here} ```
    SyntaxHighlighter.registerLanguage("js", js);
    SyntaxHighlighter.registerLanguage("py", python);

you define a custom renderer:

 const customRenderers= {
    // modify the code tag 
    code(code) {
    // node since i use ts, this code here might vary in your app
      const { node } = code;
      const { lang, value } = node;
      return (
        <div style={{ fontSize: "1.6rem" }}>
          <SyntaxHighlighter
            style={vscDarkPlus}
            language={lang}
            children={value}
          />
        </div>
      );
    },
  };

after that return this component

    return (
             <article style={{ paddingLeft: "2rem" }}>
                <ReactMarkdown  renderers={customRenderers}>
                  // place whatever you want to render
                  {blog.content} 
                </ReactMarkdown>
              </article>
    )
Related