Skip to main content
The Mermaid component renders interactive diagrams from Mermaid syntax with built-in zoom and pan controls. It supports all Mermaid diagram types and automatically adapts to light/dark themes.

Usage

import { Mermaid } from '@mintlify/components';

<Mermaid
  chart={`graph TD
    A[Start] --> B{Is it working?}
    B -->|Yes| C[Great!]
    B -->|No| D[Debug]
    D --> B`}
/>

Props

chart
string
required
The Mermaid diagram definition string. Supports all Mermaid diagram types.
className
string
Additional CSS classes to apply to the container.
ariaLabel
string
default:"Mermaid diagram"
Accessible label for the diagram (for screen readers).
placement
'top-left' | 'top-right' | 'bottom-left' | 'bottom-right'
default:"bottom-right"
Position of the zoom and pan control buttons.
actions
boolean
Whether to show the interactive controls. When undefined, controls are automatically shown when diagram height exceeds 120px. Set to true to always show controls, or false to always hide them.

Zoom and Pan Controls

The Mermaid component includes interactive controls for navigating large diagrams:
  • Zoom In: Increase diagram size (magnification)
  • Zoom Out: Decrease diagram size
  • Pan Up/Down/Left/Right: Move the diagram viewport in any direction
  • Reset View: Return to the original view (resets zoom and pan)

Control Layout

The controls are arranged in a 3×3 grid:
[ ]  [↑]  [+]
[←]  [⟲]  [→]
[ ]  [↓]  [-]
  • Top row: Pan Up, Zoom In
  • Middle row: Pan Left, Reset, Pan Right
  • Bottom row: Pan Down, Zoom Out

Auto-Show Behavior

By default, controls are automatically shown when the diagram height is at least 120px. This prevents cluttering small diagrams with unnecessary controls.

Supported Diagram Types

The Mermaid component supports all standard Mermaid diagram types:

Flowchart

<Mermaid
  chart={`graph TD
    A[Start] --> B{Is it working?}
    B -->|Yes| C[Great!]
    B -->|No| D[Debug]
    D --> B`}
/>

Sequence Diagram

<Mermaid
  chart={`sequenceDiagram
    participant Alice
    participant Bob
    Alice->>John: Hello John, how are you?
    loop Healthcheck
      John->>John: Fight against hypochondria
    end
    Note right of John: Rational thoughts prevail!
    John-->>Alice: Great!
    John->>Bob: How about you?
    Bob-->>John: Jolly good!`}
/>

Class Diagram

<Mermaid
  chart={`classDiagram
    Animal <|-- Duck
    Animal <|-- Fish
    Animal : +int age
    Animal : +String gender
    Animal: +isMammal()
    class Duck{
      +String beakColor
      +swim()
      +quack()
    }`}
/>

State Diagram

<Mermaid
  chart={`stateDiagram-v2
    [*] --> Still
    Still --> Moving
    Moving --> Still
    Moving --> Crash
    Crash --> [*]`}
/>

Entity Relationship Diagram

<Mermaid
  chart={`erDiagram
    CUSTOMER ||--o{ ORDER : places
    ORDER ||--|{ LINE-ITEM : contains
    CUSTOMER }|..|{ DELIVERY-ADDRESS : uses`}
/>

Gantt Chart

<Mermaid
  chart={`gantt
    title A Gantt Diagram
    dateFormat YYYY-MM-DD
    section Section
    A task :a1, 2024-01-01, 30d
    Another task :after a1, 20d`}
/>

Pie Chart

<Mermaid
  chart={`pie title Pets adopted by volunteers
    "Dogs" : 386
    "Cats" : 85
    "Rats" : 15`}
/>

Git Graph

<Mermaid
  chart={`gitGraph
    commit
    commit
    branch develop
    checkout develop
    commit
    commit
    checkout main
    merge develop
    commit`}
/>

User Journey

<Mermaid
  chart={`journey
    title My working day
    section Go to work
      Make tea: 5: Me
      Go upstairs: 3: Me
      Do work: 1: Me, Cat
    section Go home
      Go downstairs: 5: Me
      Sit down: 5: Me`}
/>

Examples

Basic Flowchart

<Mermaid
  chart={`graph TD
    A[Start] --> B{Is it working?}
    B -->|Yes| C[Great!]
    B -->|No| D[Debug]
    D --> B`}
/>

Complex Architecture Diagram

<Mermaid
  chart={`graph TB
    subgraph Frontend
      A[React App] --> B[Components]
      B --> C[State Management]
    end
    subgraph Backend
      D[API Gateway] --> E[Auth Service]
      D --> F[Data Service]
      E --> G[(Database)]
      F --> G
    end
    A --> D`}
/>

Controls in Different Positions

{/* Top-left */}
<Mermaid
  chart={`graph LR
    A --> B --> C`}
  placement="top-left"
  actions={true}
/>

{/* Top-right */}
<Mermaid
  chart={`graph LR
    A --> B --> C`}
  placement="top-right"
  actions={true}
/>

{/* Bottom-left */}
<Mermaid
  chart={`graph LR
    A --> B --> C`}
  placement="bottom-left"
  actions={true}
/>

{/* Bottom-right (default) */}
<Mermaid
  chart={`graph LR
    A --> B --> C`}
  placement="bottom-right"
  actions={true}
/>

Force Show/Hide Controls

{/* Always show controls (even for small diagrams) */}
<Mermaid
  chart={`flowchart LR
    A --> B`}
  actions={true}
/>

{/* Always hide controls (even for large diagrams) */}
<Mermaid
  chart={`graph TD
    A --> B --> C --> D --> E`}
  actions={false}
/>

With Custom Styling

<Mermaid
  chart={`graph LR
    A[Start] --> B[End]`}
  className="border rounded-lg p-4 bg-stone-50 dark:bg-stone-800"
/>

Large Diagram with Scrollable Container

<div className="h-[600px] w-[800px]">
  <Mermaid
    chart={`graph TD
      A[Christmas] -->|Get money| B(Go shopping)
      B --> C{Let me think}
      C -->|One| D[Laptop]
      C -->|Two| E[iPhone]
      C -->|Three| F[Car]
      D --> G[Work]
      E --> H[Fun]
      F --> I[Travel]
      G --> J[Success]
      H --> J
      I --> J`}
    placement="top-right"
  />
</div>

Multiple Diagrams (with Unique IDs)

{/* The component automatically handles unique IDs to prevent SVG conflicts */}
<Mermaid
  ariaLabel="Order processing diagram 1"
  chart={`sequenceDiagram
    participant Customer
    participant API
    Customer->>API: Create order
    API-->>Customer: Order confirmed`}
/>

<Mermaid
  ariaLabel="Order processing diagram 2"
  chart={`sequenceDiagram
    participant Customer
    participant API
    Customer->>API: Create order
    API-->>Customer: Order confirmed`}
/>

Theme Support

The Mermaid component automatically adapts to your site’s theme:
  • Light mode: Uses Mermaid’s default theme
  • Dark mode: Uses Mermaid’s dark theme
  • Font: Inherits from the parent container

Error Handling

If the diagram syntax is invalid, the component displays a user-friendly error message:
<Mermaid
  chart={`graph TD
    A[Start --> B{Invalid syntax here`}
/>
This will show:
Failed to render diagram
[Error message from Mermaid parser]

Technical Details

  • Rendering: Diagrams are rendered off-screen first, then inserted into the DOM
  • Unique IDs: Each diagram gets a unique ID to prevent SVG marker conflicts
  • Marker ID Fix: SVG marker IDs are automatically made unique to support multiple diagrams
  • Gantt Width: Gantt charts have a default width of 800px
  • Re-rendering: Diagrams automatically re-render when the chart content or theme changes

Accessibility

  • The diagram container has role="img" for screen readers
  • Custom ariaLabel can be provided for better descriptions
  • All control buttons have proper ARIA labels
  • The control group has aria-label="Diagram zoom and pan controls"

Performance

  • Diagrams are rendered asynchronously to avoid blocking the UI
  • Cancelled renders are properly cleaned up
  • Resize observers automatically manage control visibility

usePanZoom Hook

For advanced use cases, you can use the usePanZoom hook directly to build custom zoom and pan interfaces.

Import

import { usePanZoom } from '@mintlify/components';

Hook API

The usePanZoom hook returns an object with the following properties:
style
CSSProperties
CSS style object containing the transform properties for zoom and pan. Apply this to the element you want to transform.
zoomIn
() => void
Function to increase zoom level by the zoom step (0.15). Maximum zoom is 4x.
zoomOut
() => void
Function to decrease zoom level by the zoom step (0.15). Minimum zoom is 0.25x.
reset
() => void
Function to reset zoom to 1x and pan to origin (0, 0).
pan
(dx: number, dy: number) => void
Function to pan the view by the specified pixel amounts. Positive values move right/down, negative values move left/up.
panStep
number
The default pan step size in pixels (50px). Use this value for consistent pan distances.

Hook Constants

The hook uses the following internal constants:
  • MIN_SCALE: 0.25 - Minimum zoom level (25%)
  • MAX_SCALE: 4 - Maximum zoom level (400%)
  • ZOOM_STEP: 0.15 - Amount to zoom in/out per step
  • PAN_STEP: 50 - Default pan distance in pixels

Custom Implementation Example

import { usePanZoom } from '@mintlify/components';

function CustomDiagram() {
  const { style, zoomIn, zoomOut, reset, pan, panStep } = usePanZoom();

  return (
    <div className="relative h-96 overflow-hidden">
      {/* Custom controls */}
      <div className="absolute top-2 right-2 flex gap-2">
        <button onClick={zoomIn}>+</button>
        <button onClick={zoomOut}>-</button>
        <button onClick={reset}>Reset</button>
        <button onClick={() => pan(0, panStep)}></button>
        <button onClick={() => pan(0, -panStep)}></button>
        <button onClick={() => pan(panStep, 0)}></button>
        <button onClick={() => pan(-panStep, 0)}></button>
      </div>

      {/* Your content with zoom/pan applied */}
      <div style={style}>
        <img src="/diagram.png" alt="Diagram" />
      </div>
    </div>
  );
}

Advanced Usage with Keyboard Controls

import { usePanZoom } from '@mintlify/components';
import { useEffect } from 'react';

function KeyboardControlledDiagram() {
  const { style, zoomIn, zoomOut, reset, pan, panStep } = usePanZoom();

  useEffect(() => {
    const handleKeyDown = (e: KeyboardEvent) => {
      switch (e.key) {
        case '+':
        case '=':
          zoomIn();
          break;
        case '-':
        case '_':
          zoomOut();
          break;
        case '0':
          reset();
          break;
        case 'ArrowUp':
          pan(0, panStep);
          break;
        case 'ArrowDown':
          pan(0, -panStep);
          break;
        case 'ArrowLeft':
          pan(panStep, 0);
          break;
        case 'ArrowRight':
          pan(-panStep, 0);
          break;
      }
    };

    window.addEventListener('keydown', handleKeyDown);
    return () => window.removeEventListener('keydown', handleKeyDown);
  }, [zoomIn, zoomOut, reset, pan, panStep]);

  return (
    <div style={style}>
      <YourContent />
    </div>
  );
}

ZoomControls Component

The ZoomControls component provides the interactive control panel used by the Mermaid component. You can use it independently for other zoomable content.

Import

import { ZoomControls } from '@mintlify/components';

Props

onZoomIn
() => void
required
Callback function when zoom in button is clicked.
onZoomOut
() => void
required
Callback function when zoom out button is clicked.
onReset
() => void
required
Callback function when reset button is clicked.
onPan
(dx: number, dy: number) => void
required
Callback function when pan buttons are clicked. Receives x and y delta values.
panStep
number
required
The distance in pixels to pan for each button click.
placement
'top-left' | 'top-right' | 'bottom-left' | 'bottom-right'
Position of the controls within the parent container. Defaults to "bottom-right".

Usage with usePanZoom

import { usePanZoom, ZoomControls } from '@mintlify/components';

function CustomZoomableContent() {
  const { style, zoomIn, zoomOut, reset, pan, panStep } = usePanZoom();

  return (
    <div className="relative h-96 overflow-hidden">
      <ZoomControls
        onZoomIn={zoomIn}
        onZoomOut={zoomOut}
        onReset={reset}
        onPan={pan}
        panStep={panStep}
        placement="top-right"
      />
      <div style={style}>
        <YourContent />
      </div>
    </div>
  );
}

Source

View the source code:
  • Mermaid: packages/components/src/components/mermaid/mermaid.tsx:27
  • usePanZoom Hook: packages/components/src/components/mermaid/use-pan-zoom.ts:25
  • Zoom Controls: packages/components/src/components/mermaid/zoom-controls.tsx:43

Build docs developers (and LLMs) love