0

Using nextjs-13

I want to use prism-react-renderer inside markdown-to-jsx to highlight my code, and I wrote the following code as I understand it

page.tsx

import fs from "fs";
import Markdown from "markdown-to-jsx";
import matter from "gray-matter";
import { Highlight,themes} from "prism-react-renderer";
import React, { useState } from 'react';

const getPost = () => {
  const file = "posts/test.md";
  const content = fs.readFileSync(file, "utf8");
  const matterResult = matter(content);
  return matterResult;
};

const Page = () => {
  const post = getPost();
  return (
    <Markdown options={{
      wrapper: 'article', slugify: str => str,
      overrides: {
        pre: CodeBlock
      }
    }} className="markdown">{post.content}</Markdown>
  );
};

const CodeBlock = ({ children }: any) => {
  const code = children.props.children;
  const language = children.props.className?.replace("lang-", "").trim();

  return (
    <Highlight code={code} language={language} theme={themes.dracula}>
      {({ tokens, className, style, getLineProps, getTokenProps }) => (
        <pre className={className} style={style}>
          {tokens.map((line, i) => (
            <div key={i} {...getLineProps({ line })}>
              <span>{i + 1}</span>
              {line.map((token, key) => (
                <span key={key} {...getTokenProps({ token })} />
              ))}
            </div>
          ))}
        </pre>
      )}
    </Highlight>
    
    //! This is OK
    // <pre className={`language-${language}`}>
    //   <code>
    //     {code}
    //   </code>
    // </pre>
)}

export default Page;

But I got A ERR when running pnpm run dev

Unhandled Runtime Error

Error: (0 , import_react.useState) is not a function or its return value is not iterable
Call Stack
themeToDict_default
node_modules/.pnpm/prism-react-renderer@2.0.3_react@18.2.0/node_modules/prism-react-renderer/dist/index.js (2592:4)
useThemeDictionary
node_modules/.pnpm/prism-react-renderer@2.0.3_react@18.2.0/node_modules/prism-react-renderer/dist/index.js (2770:26)

I've checked the code for the prompt, but I've got no idea

I tried this demo with the same version and it works fine

What's the problem and how can I solve it?

2 Answers2

1

I had the same issue. And while I do not know the 'why'. I do know that it was solved for me by using the use client in the component that renders the code block.

It might indeed be due to Next.js 13? When I could not find a solution I tried another approach, leading me to issues as well. But this answer led me to try the solution here too.

So it probably has to do with the fact that the highlighter needs to run at the client and since Next.js 13 defaults to the server, this issue pops up.

Rutger
  • 966
  • 8
  • 6
0

You'll need to put CodeBlock in a separate file, and add the 'use client' directive at the top of that file.

I was running into this issue as well, and that fixed it for me.

Mykhaylo
  • 39
  • 4