Adding Mermaid Diagram Support to the Browser Notepad on This Site
Following the implementation of the Browser Memo and the URL Sharing Feature, I have now added a diagram drawing feature using Mermaid syntax.
This article summarizes the technology selection and implementation points for extending the existing Markdown preview function to draw and preview diagrams based on text.
1. Background and Motivation: Completing Thought Organization in One Tabโ
The currently operating "Browser Notepad" features Markdown preview, local storage persistence, and URL sharing, making it very useful for daily quick note-taking.
However, text alone was limiting when trying to organize complex processing flows or configuration diagrams. At the same time, opening external tools like Miro or Draw.io felt a bit excessive for the context of "organizing thoughts," and the cost of context switching was a concern.
Therefore, I decided to add Mermaid support with the goal of "drawing diagrams within the same tab with the same ease as text."
2. Technology Selection and Implementation Strategyโ
I adopted mermaid, which is the de facto standard in the Markdown ecosystem, as the drawing engine.
Since the existing preview function is implemented with react-markdown, I took the approach of intervening in its rendering flow.
- Use the
componentsprop ofreact-markdownto hijack the rendering of specific HTML tags. - Detect code blocks (
<code>) where the language specification class islanguage-mermaid. - Replace the detected blocks with a custom
<MermaidPreview>component instead of the standard code display.
3. Implementation Pointsโ
Implementation of MermaidPreview Componentโ
I extracted the Mermaid drawing logic as a React component. Its main role is to convert the received text (Mermaid syntax) into SVG and reflect it in the DOM.
mermaid.run: Used the API to scan DOM elements and generate SVGs.- Repaint Control: Used
useEffectto update the diagram whenever the input text changes. - Theme Synchronization: Adjusted it to detect Docusaurus's dark mode setting (
html[data-theme='dark']) and automatically switch the Mermaid theme as well.
Also, to avoid dependency conflicts (Ghost Dependencies) in the Docusaurus environment, I explicitly added the package via pnpm add mermaid.
Component Replacement in React Markdownโ
This is a common technique used in blogs, customizing rendering via the components prop of react-markdown.
The key point here is parsing class names with regular expressions.
import ReactMarkdown from 'react-markdown';
import remarkGfm from 'remark-gfm';
import MermaidPreview from './MermaidPreview'; // Custom component
// ...
<ReactMarkdown
remarkPlugins={[remarkGfm]}
components={{
code(props) {
const { children, className, node, ...rest } = props;
// Detect code blocks with the "language-mermaid" class using regex
const match = /language-(\w+)/.exec(className || '');
if (match && match[1] === 'mermaid') {
// Remove trailing newline and pass to Mermaid component
return <MermaidPreview chart={String(children).replace(/\n$/, '')} />;
}
// Render as a normal code block otherwise
return <code className={className} {...rest}>{children}</code>;
}
}}
>
{previewText}
</ReactMarkdown>
4. UX Design Decision: Adopting Standard Syntaxโ
During implementation, there was a debate on whether to use "custom syntax or standard code block syntax," but I decided to adopt the standard code block syntax (fence code block).
graph TD;
A-->B;
The reasons are the following three points:
- Interference Avoidance: To prevent normal notes (words like "graph") from being interpreted as diagrams unintentionally.
- Portability: To ensure that notes can be copied and pasted directly into GitHub Issues or other tools commonly used by engineers (GitHub, Notion, VSCode) and still function as diagrams.
- Technical Standard: Because it is the most standard way of extension in the Markdown ecosystem.
5. Results and Outcomeโ
With this addition, typing graph TD; A-->B; immediately displays the flowchart in the preview screen on the right.
Additionally, since the previously implemented URL sharing feature targets text data, diagrams written in Mermaid syntax can also be shared seamlessly with others via a single URL.
Summaryโ
Introducing Mermaid to an app with Markdown preview can be implemented relatively smoothly using the extension mechanism of react-markdown.
- Component Replacement is Key: Hijack the rendering of the
codetag with thecomponentsprop to insert Mermaid processing. - Stick to Standard Syntax: Adopt
```mermaidinstead of custom syntax to maintain compatibility with other tools and ease of copy-pasting. - Compatibility with URL Sharing: Text-based diagrams have small data sizes and work very well with the LZString compression-based URL sharing feature.
This has further enhanced the tool as a practical text-based thought organizer.