Charts
Fences tagged mermaid whose diagram is pie or xychart-beta become native
data_visualization blocks. Slack renders the chart itself, with no image
service involved.
### Error budget by service ```mermaid pie "billing-api" : 62 "checkout" : 28 "search" : 10 ```
Block Kit JSON
…
xychart-beta produces bar or line charts. This one asks for line; swapping the keyword
to bar gives you the other:
```mermaid xychart-beta title "p95 latency (ms)" x-axis ["Mon", "Tue", "Wed", "Thu", "Fri"] y-axis "ms" line [212, 198, 240, 205, 190] ```
Block Kit JSON
…
Slack's chart block caps counts at 12 pie segments, 12 series, and 20 data points. A chart that exceeds them falls back to the same chain other mermaid diagrams use: a configured renderer, then preformatted source. Overlong text does not cause fallback. Instead, titles are truncated to 50 characters and labels to 20 in the native block, each with a degradation. Mixed bar-and-line charts render as bar (Slack charts are single-type), and a missing chart title falls back to the nearest preceding heading. slackmark also enforces a defensive cap of 2 native charts per message (a community-reported Slack limit).
Other mermaid diagrams
Only pie and xychart-beta have native Slack equivalents. Every other
mermaid diagram (flowcharts, sequence diagrams, …) is handled in order:
- Configured image renderers.
options.renderersis consulted for the fence language. Renderers turn the diagram into animageblock. - Preformatted source. With no renderer (the default), the mermaid source is emitted as a code block.
Step 2 is what the default converter does, and it is worth seeing before you decide whether you need a renderer at all. The diagram stays legible; it just is not drawn:
```mermaid sequenceDiagram Agent->>Slack: post message Slack-->>Agent: ok ```
Block Kit JSON
…
Four hosted-URL renderers ship in the slackmark/renderers subpath, and two of
them handle mermaid:
import { createConverter } from "slackmark";
import { MermaidInkRenderer } from "slackmark/renderers";
const converter = createConverter({
renderers: [new MermaidInkRenderer()],
});MermaidInkRenderer and KrokiRenderer compose public image URLs containing
the encoded diagram source. Slack fetches the image. Core still performs no
network I/O. Treat hosted renderers as an explicit data-egress opt-in, and pass
baseUrl to point at a self-hosted deployment. Slack must be able to fetch that
deployment anonymously, and the diagram source is still in the URL either way:
import { KrokiRenderer } from "slackmark/renderers";
new KrokiRenderer({ baseUrl: "https://kroki.internal.example" });A renderer that produces image bytes instead of a URL additionally needs an
uploader. FetchSlackUploader from slackmark/slack implements Slack's
external upload flow. It needs the files:write scope, and files:read as well
if you set waitForProcessing: true.
The same renderer list handles other fenced languages. KrokiRenderer accepts
PlantUML, D2, Graphviz, and its other supported aliases. QuickChartRenderer
accepts Chart.js JSON. Display math is offered to CodeCogsRenderer or a local
bytes renderer before its preformatted fallback.
For local Mermaid and KaTeX PNGs in Node, see Rasterize content.