Package Exports
- mermaid-renderer-package
- mermaid-renderer-package/dist/index.js
- mermaid-renderer-package/dist/index.mjs
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (mermaid-renderer-package) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
Mermaid Renderer Package
A versatile and lightweight solution for rendering Mermaid diagrams in React applications, optimized for Server-Side Rendering (SSR) environments like Next.js. This package provides modular tools for integrating Mermaid into your Markdown processing pipeline, ensuring smooth rendering without common SSR build issues.
Why This Package?
Many existing solutions for rendering Mermaid diagrams in web applications, especially those leveraging unified
(Remark/Rehype) for Markdown processing, often fall short in Server-Side Rendering (SSR) environments like Next.js. They typically attempt to pre-render Mermaid diagrams into SVG on the server, which frequently introduces heavy, browser-specific dependencies (like playwright
) that cause build failures in Node.js environments.
This package addresses these critical pain points by offering a flexible, modular, and SSR-friendly approach:
SSR-Optimized Backend Processing: Our custom
rehype
plugin (rehypeMermaid
) intelligently transforms Mermaid code blocks into lightweight HTML placeholders with embedded Base64-encoded Mermaid syntax. This process occurs entirely in Node.js, without introducing any browser-specific dependencies, thus eliminating common SSR build errors.Flexible Frontend Rendering: We provide a dedicated React component (
MermaidComponent
) that takes the Mermaid syntax and leverages themermaid.js
library to render the diagrams client-side. This ensures compatibility with React's rendering lifecycle and avoids direct DOM manipulation issues.Modular and Reusable: The solution is broken down into distinct, reusable parts:
- A
rehype
plugin for Markdown processing pipelines. - A React component for easy integration into React applications.
- A universal rendering function for direct SVG generation in any JavaScript environment. This modularity allows developers to pick and choose the tools that best fit their specific tech stack and requirements.
- A
Lightweight and Efficient: By avoiding unnecessary heavy dependencies, the package remains lean, contributing to faster build times and better application performance.
Features
- SSR-Friendly: Seamlessly integrate Mermaid diagrams into Next.js, Gatsby, and other SSR frameworks without build issues.
- Unified Ecosystem Compatible: Works perfectly with
remark
andrehype
for robust Markdown parsing and HTML transformation. - React Integration: Easy-to-use React component for client-side rendering.
- Flexible Rendering Options: Supports both pipeline-based processing and direct programmatic rendering of Mermaid syntax to SVG.
- Lightweight: Minimal dependencies, ensuring a small footprint.
Installation
npm install mermaid-renderer-package mermaid unified remark-parse remark-rehype rehype-stringify html-react-parser unist-util-visit
# or yarn add ...
Usage
This package provides three main ways to use its functionality, catering to different integration needs:
1. Using with Unified (Remark/Rehype) in a Next.js/SSR Environment
This is the recommended approach for applications that process Markdown on the server (e.g., for static site generation or server-side rendering) and render content with React on the client.
a. Backend (e.g., lib/posts.ts
or API route)
Use rehypeMermaid
in your unified
processing pipeline to transform Mermaid code blocks into div
elements with data-mermaid
attributes.
// lib/posts.ts (example)
import { unified } from 'unified';
import remarkParse from 'remark-parse';
import remarkRehype from 'remark-rehype';
import rehypeStringify from 'rehype-stringify';
import rehypeHighlight from 'rehype-highlight'; // For code highlighting
import { rehypeMermaid } from 'mermaid-renderer-package'; // Import our plugin
import { visit } from 'unist-util-visit'; // Required by rehypeMermaid
export async function processMarkdown(markdownContent: string) {
const processedContent = await unified()
.use(remarkParse)
.use(remarkRehype, { allowDangerousHtml: true }) // Important for custom HTML
.use(rehypeHighlight, { detect: false, subset: false }) // Optional: for code highlighting
.use(rehypeMermaid) // Our custom Mermaid plugin
.use(rehypeStringify)
.process(markdownContent);
return processedContent.toString(); // This HTML will contain <div data-mermaid="...">
}
b. Frontend (e.g., app/posts/[postId]/page.tsx
or any React component)
Use html-react-parser
to parse the HTML string and replace the div[data-mermaid]
elements with the MermaidComponent
.
// app/posts/[postId]/page.tsx (example)
'use client'; // For Next.js App Router
import React from 'react';
import parse, { domToReact, DOMNode } from 'html-react-parser';
import { MermaidComponent } from 'mermaid-renderer-package'; // Import our React component
import { Element } from 'domhandler'; // Import Element type for type guarding
interface PostProps {
contentHtml: string; // HTML string processed by the backend
}
const PostContent: React.FC<PostProps> = ({ contentHtml }) => {
const parsedContent = parse(contentHtml, {
replace: (domNode: DOMNode) => {
if (domNode.type === 'tag') {
const element = domNode as Element; // Assert to Element type
// Replace our custom data-mermaid div with MermaidComponent
if (element.attribs && element.attribs['data-mermaid']) {
const code = Buffer.from(
element.attribs['data-mermaid'],
'base64'
).toString('utf-8');
return <MermaidComponent chart={code} />;
}
// Optional: Handle code blocks to prevent html-react-parser from escaping their content
// This ensures highlight.js works correctly
if (element.name === 'code') {
return <code {...element.attribs}>{domToReact(element.children as DOMNode[])}</code>;
}
}
// For all other nodes, continue with default parsing
if (domNode.children) {
return domToReact(domNode.children as DOMNode[]);
}
return null;
},
});
return <div>{parsedContent}</div>;
};
export default PostContent;
2. Using the React Component Directly
If you have the Mermaid syntax string directly in your React application (e.g., fetched from an API or hardcoded), you can use MermaidComponent
without the unified
pipeline.
// MyReactComponent.tsx
'use client';
import React from 'react';
import { MermaidComponent } from 'mermaid-renderer-package';
const myMermaidCode = `
graph TD
A[Start] --> B{Process}
B --> C[End]
`;
const MyReactComponent: React.FC = () => {
return (
<div>
<h1>My Diagram</h1>
<MermaidComponent chart={myMermaidCode} />
</div>
);
};
export default MyReactComponent;
3. Using the Universal Rendering Function
For scenarios where you need to render Mermaid to SVG programmatically in any JavaScript environment (Node.js, browser, etc.) without React or unified
integration.
// render-script.js
import { renderMermaid } from 'mermaid-renderer-package';
const diagramCode = `
flowchart LR
A --- B
B --> C
`;
async function generateSvg() {
try {
const svg = await renderMermaid(diagramCode, 'unique-id-for-render');
console.log('Generated SVG:', svg);
// You can then inject this SVG into your DOM or save it to a file
} catch (error) {
console.error('Failed to render Mermaid:', error);
}
}
generateSvg();
Development & Contribution
Contributions are welcome! Please refer to the project's GitHub repository for development guidelines and how to contribute.
License
This project is licensed under the MIT License.