Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issues running in browser with react-markdown #1

Closed
humphd opened this issue May 7, 2023 · 8 comments
Closed

Issues running in browser with react-markdown #1

humphd opened this issue May 7, 2023 · 8 comments

Comments

@humphd
Copy link

humphd commented May 7, 2023

Based on the warning in the recent release of remark-mermaidjs, I've tried migrating to rehype-mermaidjs. I'm having some issues using it as a drop-in replacement for what I had previously.

Here is what I'm doing:

import ReactMarkdown from "react-markdown";
import rehypeMermaid from "rehype-mermaidjs";
import remarkGfm from "remark-gfm";
...
    <ReactMarkdown
      children={children}
      { /* Previously I did [remarkGfm, remarkMermaid] and it worked well */}
      remarkPlugins={[remarkGfm]}
      rehypePlugins={[rehypeMermaid]}

This ends up crashing like so at runtime:

Uncaught caught Error: `runSync` finished async. Use `run` instead
    at assertDone (index.js:566:11)
    at Function.runSync (index.js:352:5)
    at ReactMarkdown (react-markdown.js:106:30)
    at renderWithHooks (react-dom.development.js:16305:18)
    at mountIndeterminateComponent (react-dom.development.js:20074:13)
    at beginWork (react-dom.development.js:21587:16)
    at HTMLUnknownElement.callCallback2 (react-dom.development.js:4164:14)
    at Object.invokeGuardedCallbackDev (react-dom.development.js:4213:16)
    at invokeGuardedCallback (react-dom.development.js:4277:31)
    at beginWork$1 (react-dom.development.js:27451:7)

I also note that upon installation, I get this warning:

warning "rehype-mermaidjs > mermaid-isomorphic > mermaid > @khanacademy/[email protected]" has incorrect peer dependency "[email protected]"

My goal is to be able to use a plugin to render Mermaid blocks in React Markdown. Perhaps this package isn't the best fit? Or maybe I'm missing something.

@remcohaszing
Copy link
Owner

I didn’t realize this at the moment of writing, but this is another breaking change. I’ll add this to the release notes. Both remark-mermaidjs@5 and rehype-mermaidjs are now asynchronous in the browser. There’s not much I can do about it, as mermaid.render() is now asynchronous. Unfortunately remark-markdown can’t use async plugins at the moment (remarkjs/react-markdown#680).

I recommend to stay on remark-mermaidjs@4 for now. Most of the benefits don’t affect browser usage anyway.

I also note that upon installation, I get this warning:

warning "rehype-mermaidjs > mermaid-isomorphic > mermaid > @khanacademy/[email protected]" has incorrect peer dependency "[email protected]"

A fix for this hast just been merged (mermaid-js/mermaid#4350 (comment)). This warning will go away soon.

@remcohaszing remcohaszing closed this as not planned Won't fix, can't repro, duplicate, stale May 8, 2023
@ngnhat
Copy link

ngnhat commented Jun 28, 2023

@remcohaszing They have merged it. I hope this issue gets fixed soon.

@remcohaszing
Copy link
Owner

remarkjs/react-markdown#680 is still open.

As for the warning, that has been fixed. You may need to regenerate your lockfile.

tatumroaquin added a commit to tatumroaquin/mern-blog that referenced this issue Sep 19, 2023
- pin rehype-raw to v6.1.1 while waiting for type updates remarkjs/react-markdown#769
- pin remark-mermaidjs to v4.1.1 according to a similar issue remcohaszing/rehype-mermaid#1
@tobiasbueschel
Copy link

Thanks for all your work with this the mermaid rehype and remark plugins @remcohaszing 🙏 It looks like remarkjs/react-markdown#680 will take a while to resolve.

Out of curiosity, do you recommend any other React markdown renderer that works well with rehype-mermaid / remark-mermaid? :)

@wooorm
Copy link

wooorm commented Oct 15, 2024

You can use unified with rehype-mermaid directly!

@remcohaszing
Copy link
Owner

☝️ This. react-markdown is synchronous. That solves 99% of use cases. Supporting async stuff in React in a way that’s compatible with client side, server side, state, server components, etc, is more complex and takes though, time, and effort. react-markdown isn’t very complex as-is. All the pieces are there. You can create your own async version in your project that meets your specific needs, based on a unified pipeline.

@tobiasbueschel
Copy link

Thanks @wooorm & @remcohaszing for the quick reply!

I'm still new to the unified ecosystem, hence, hope you don't mind if I ask a related question here:

My use case is to render Markdown that gets streamed as a message coming from an LLM which contains Mermaid diagrams, these are then rendered in a React.js application.

Going directly from Markdown to Mermaid using remark-mermaidjs sounded like the most straightforward approach for me, as it abstracts away the entire MD > HTML > SVG conversion and I can plug it in directly:

// Option 1

<Markdown
    remarkPlugins={[remarkMermaid]}
    components={{
      code: Code,
      table: Table,
    }}
  >
    {content}
</Markdown>

If I use unified directly, I suppose one would implement it in such a way:

// Option 2

const production = {Fragment: prod.Fragment, jsx: prod.jsx, jsxs: prod.jsxs}

const text = `Here is a Mermaid diagram: \`\`\`mermaid
  flowchart LR
    A[Hard] -->|Text| B(Round)
    B --> C{Decision}
    C -->|One| D[Result 1]
    C -->|Two| E[Result 2]
\`\`\`
`;


function useProcessor(text) {
  const [Content, setContent] = useState(createElement(Fragment));

  useEffect(
    function () {
      (async function () {
        const file = await unified()
          .use(remarkParse)
          .use(remarkRehype)
          .use(rehypeDocument)
          .use(rehypeFormat)
          .use(rehypeReact, production)
          .process(text);

        setContent(file.result);
      })();
    },
    [text]
  );

  return Content;
}

Hence, I'm wondering:

  1. Will option 2 be better in the long-term as it allows for more flexibility and is that why you suggest for most people to use rehype-mermaid over remark-mermaidjs?

  2. For the above use case regarding streaming of messages, is there any option to skip remark-mermaidjs / rehype-mermaid entirely from executing before the code block has been fully received by the client, so that it doesn't even trigger the errorFallback but instead just passes the text to the next plugin until the Mermaid diagram has been fully loaded and can be rendered?

@wooorm
Copy link

wooorm commented Oct 17, 2024

It’s better to post such adjacent questions into discussions.

You’re missing something. Do not use remark-mermaidjs. With either approach. Use rehype-mermaid. rehypeMermaid should be in both the 1st and 2nd approach.

I’d call the 1st approach less flexible. It abstracts things away. With approach 2, you can do more things.

You don’t need rehypeFormat or rehypeDocument. Read about the plugins in all the different examples and make a personal choice whether you want them.

How to do “streaming” is not much related to this. It is also often asked already. See for example https://github.com/orgs/remarkjs/discussions/1372#discussioncomment-10784489.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants