Usage
Place a diagram with <Mermaid>, configure the palette once, and let it follow the page's theme.
The component
import { Mermaid } from '@sigx/mermaid';
<Mermaid code="graph TD; A-->B;" title="Flow" />
<Mermaid code={source} eager />
| Prop | Type | Description |
|---|---|---|
code | string | Required. The diagram definition. |
title | string | Rendered as a <figcaption> and used as the SVG's accessible name. |
options | MermaidOptions | Per-instance overrides, merged over the global config. |
eager | boolean | Render on mount instead of on scroll-into-view. Default false. |
Anything else lands on the <figure> — id, class, style, data-*, aria-*, DOM event handlers. class is composed with the component's own rather than replacing it:
<Mermaid code={source} id="architecture" class="my-diagram" />
// → <figure class="sigx-mermaid my-diagram" id="architecture" …>
title is the exception: it is this component's caption, so it is not forwarded as the HTML tooltip attribute.
The source is emitted as a <pre> and only hidden once the SVG lands. So a diagram that has not rendered — no JavaScript yet, or a syntax error — still shows its definition instead of a blank frame.
Configuration
Set global options once, wherever your app starts up:
import { configureMermaid } from '@sigx/mermaid';
configureMermaid({
themes: { light: 'neutral', dark: 'dark' },
config: { flowchart: { curve: 'basis' } },
});
Calls merge, so several modules can each contribute a slice, and any component can override with options.
| Option | Default | Description |
|---|---|---|
themes | { light: 'default', dark: 'dark' } | Appearance per colour scheme. |
securityLevel | 'strict' | Passed to mermaid. Raising it lets diagrams emit raw HTML and click handlers. |
config | {} | Merged into mermaid.initialize(). themeVariables merges rather than replaces. |
resolveColorScheme | — | Override colour-scheme detection entirely. |
Matching your palette
Each scheme takes a mermaid theme name or { theme, variables }:
configureMermaid({
themes: {
light: { theme: 'base', variables: { primaryColor: '#f6f8fa', lineColor: '#d1d9e0' } },
dark: { theme: 'base', variables: { primaryColor: '#161b22', lineColor: '#3d444d' } },
},
});
Pair variables with theme: 'base' — base is the theme mermaid intends to be recoloured; the others largely ignore overrides.
variables may be a function, evaluated at render time rather than at config time. That is how diagrams track a daisyUI or Tailwind theme swap without restating the palette:
const cssVar = (n: string) => getComputedStyle(document.documentElement).getPropertyValue(n).trim();
const fromTokens = () => ({
background: cssVar('--b1'),
primaryColor: cssVar('--b2'),
primaryTextColor: cssVar('--bc'),
lineColor: cssVar('--bc'),
});
configureMermaid({
themes: { light: { theme: 'base', variables: fromTokens }, dark: { theme: 'base', variables: fromTokens } },
});
Precedence, lowest first: package defaults → global config → per-call options.config → the active scheme's variables. themeVariables merges at each step, so overriding one colour keeps the rest.
The one variable the package sets
| Variable | Default | Why |
|---|---|---|
edgeLabelBackground | the page background | mermaid hardcodes a light grey in every built-in theme, including the dark ones, so an edge label lands as a highlighter smear across a dark diagram. |
The page background rather than transparent, because the chip's job is to occlude the line running under it. Set it yourself to override — 'transparent' included. When no background is painted the canvas is white, which is what mermaid's default already assumes, so nothing is applied.
Theme detection
In order, first match wins:
- an explicit
resolveColorScheme data-themeof exactlylight/darkon<html>- the computed
color-scheme— how named daisyUI themes likenightorcupcakeresolve - a
.darkclass on<html>(the Tailwind convention) - the page's actual background colour
Note what is not on that list: prefers-color-scheme. A page that has not opted into dark mode renders light no matter what the OS prefers, so keying off the OS puts a dark diagram on a white page.
Reading the background answers the question actually being asked — is this diagram about to sit on something dark? — and it works whether the site themes itself with data-theme, a class, or a bare @media (prefers-color-scheme: dark) block that declares no color-scheme. A page with no background at all is canvas white, so: light.
If your page is dark in a way none of these can see, say so directly:
configureMermaid({ resolveColorScheme: () => (myStore.dark ? 'dark' : 'light') });
Re-rendering
When the resolved appearance changes, already-rendered diagrams re-render; ones that have not drawn yet pick up the new theme when they do.
"Changes" means the colour scheme, the theme name, or the resolved variables — all three, because with per-scheme variables both schemes usually name base, and a daisyUI swap between two light themes changes neither the scheme nor the name while changing every colour.
The watcher fires on data-theme / class / style mutations on <html> and on prefers-color-scheme. A theme delivered purely by swapping a stylesheet is not observable — call renderDiagram again, or toggle an attribute.
Styling
@sigx/mermaid/styles is cosmetic. Everything functional is done in JS with the hidden attribute, so a site that skips the stylesheet still behaves correctly.
Override the custom properties on .sigx-mermaid: --sigx-mermaid-gap, --sigx-mermaid-radius, --sigx-mermaid-padding, --sigx-mermaid-bg, --sigx-mermaid-border, --sigx-mermaid-muted, --sigx-mermaid-error, --sigx-mermaid-min-height.
Next steps
- SSG integration —
mermaidfences in MDX.
