Documents
Home>Documents>Dev>Frontend

React Markdown Rendering with Code Highlighting and Mermaid

5 min readFeb 21, 2026Feb 22, 2026

The Challenges of Markdown Rendering

In hr_blog2.0, blog posts are written in Markdown. The rendering system needs to support code highlighting, Mermaid diagrams, tables, and more.

Rendering Pipeline

graph TD
    A[Markdown 텍스트] --> B[react-markdown]
    B --> C[remark-gfm]
    B --> D[remark-math]
    C --> E[테이블, 체크박스]
    D --> F[수학 수식]
    B --> G[rehype-highlight]
    G --> H[코드 하이라이팅]
    B --> I[커스텀 렌더러]
    I --> J[Mermaid 다이어그램]
    I --> K[이미지 최적화]

The MarkdownRenderer Component

import ReactMarkdown from 'react-markdown';
import remarkGfm from 'remark-gfm';
import rehypeHighlight from 'rehype-highlight';
import mermaid from 'mermaid';

function MarkdownRenderer({ content }: { content: string }) {
  return (
    <ReactMarkdown
      remarkPlugins={[remarkGfm]}
      rehypePlugins={[rehypeHighlight]}
      components={{
        code({ className, children }) {
          if (className === 'language-mermaid') {
            return <MermaidDiagram chart={String(children)} />;
          }
          return <code className={className}>{children}</code>;
        }
      }}
    >
      {content}
    </ReactMarkdown>
  );
}

The Mermaid Component

function MermaidDiagram({ chart }: { chart: string }) {
  const ref = useRef<HTMLDivElement>(null);

  useEffect(() => {
    if (ref.current) {
      mermaid.initialize({ theme: 'dark' });
      mermaid.render('mermaid-' + id, chart)
        .then(({ svg }) => {
          ref.current!.innerHTML = svg;
        });
    }
  }, [chart]);

  return <div ref={ref} className="mermaid-container" />;
}

Automatic Table of Contents (TOC) Generation

function extractHeadings(content: string) {
  const headings: Heading[] = [];
  const regex = /^(#{1,3})\s+(.+)$/gm;
  let match;

  while ((match = regex.exec(content)) !== null) {
    headings.push({
      level: match[1].length,
      text: match[2],
      id: slugify(match[2])
    });
  }
  return headings;
}

Every post on this blog is rendered through this pipeline.

Tags
MarkdownReactMermaidcode highlightingrendering