astro-dgmo
v0.9.2
Published
Astro integration to render DGMO diagrams from fenced code blocks at build time. Powered by @diagrammo/dgmo.
Maintainers
Readme
astro-dgmo
Render DGMO diagrams from fenced code blocks in your Astro site at build time. Powered by @diagrammo/dgmo and the framework-agnostic remark-dgmo core. Zero client JavaScript by default.
📖 Setup guide: diagrammo.app/embed#astro · 🔭 Live showcase: every chart type rendered through astro-dgmo — every block is in showcase mode, so hovering a diagram reveals its copy / open-in-editor footer.
sequence
Client -POST /login-> API
API -validate-> Auth
Auth -JWT-> API
API -200 OK-> Client…in any .md or .mdx file becomes a beautifully rendered SVG, inlined into the page. Every diagram is rendered twice at build time (light + dark palettes) and follows the host's color-mode toggle via shipped CSS.
Chart types & visual authoring
One small plain-text language, 45 chart types — flowcharts, sequence, state, class, ER, C4, org charts, gantt, maps, mind maps, and the full bar/line/pie/area/sankey family. Browse every type with live examples in the language reference.
Prefer to author visually? Draft diagrams in the Diagrammo desktop app or the online editor — live preview, autocomplete, optional vim keybindings, 7 themeable palettes, and one-click PNG/SVG export — then paste the dgmo block into your docs. More at diagrammo.app.
Install
pnpm add astro-dgmo @diagrammo/dgmo
# or
npm install astro-dgmo @diagrammo/dgmo@diagrammo/dgmo is a peer dependency.
Quick start
Add the integration to astro.config.mjs:
import { defineConfig } from 'astro/config';
import dgmo from 'astro-dgmo';
export default defineConfig({
integrations: [dgmo()],
});Then import remark-dgmo/client.css in a global layout — Astro 6's IntegrationHook has no programmatic stylesheet injection, so this manual step is unavoidable:
---
// src/layouts/Base.astro
import 'remark-dgmo/client.css';
---That's the whole integration. Anywhere in your Markdown or MDX content, write a fenced block with the language dgmo:
```dgmo
pie Language Mix
TypeScript 45
Python 30
Rust 25
```At build time the block is replaced with an inline <svg> wrapped in a <figure class="dgmo dgmo--diagram">. No client JavaScript is shipped unless you opt into showcase mode.
Pass options to the integration to override defaults:
dgmo({ mode: 'showcase', palette: 'catppuccin', colorMode: 'auto' });See remark-dgmo for the full options matrix — astro-dgmo forwards everything through.
Per-block overrides
Append options to the fence info string. Tokens are space-separated; values may be quoted.
```dgmo showcase title="Login flow" palette=catppuccin theme=light
sequence
A -> B
```| Token | Effect |
| ------------------------------------------------------- | ----------------------------------- |
| diagram / showcase | Set mode for this block |
| palette=<name> | Override palette |
| theme=light / theme=dark / theme=transparent | Override theme (single-render only) |
| colorMode=auto / colorMode=light / colorMode=dark | Override color-mode strategy |
| title="…" | Add a caption (<figcaption>) |
| source / noSource | Force source view + toggle on/off |
| copy / noCopy | Force copy button on/off |
| expand / noExpand | Force expand (full-screen) on/off |
| openInEditor / noOpenInEditor | Force editor link on/off |
See the remark-dgmo README for the full option matrix.
Live links (on by default)
A fence can name a published Diagrammo Cloud diagram instead of carrying its own source, so the page stops going stale the day it is written:
```dgmo
live-link dgm_01HQ3RSTUV
```No configuration needed — this resolves out of the box. To stop your build fetching anything:
// astro.config.mjs
integrations: [dgmo({ liveLink: { enabled: false } })];Switched off, the fence renders a small card naming the diagram and linking through to it, plus a hover-revealed "Show this diagram here" link to the guide, and the build warns. See the live links guide.
The build resolves it, renders it exactly like any other block, and writes what
it fetched to .dgmo/references/<id>.json — commit that directory. It is
what makes your build reproducible, offline-capable, and independent of our
uptime: if we are unreachable, the site builds from the committed copy and warns.
⚠️ If your site sets a Content-Security-Policy it must allow
connect-src https://api.diagrammo.app. Without it the diagram still renders
(it was baked at build time) but never refreshes, and nothing can report that —
the report would be blocked too.
When a diagram changes after you build
By default the page notices — a small link to the live diagram — rather than
re-rendering it. Re-rendering means shipping the dgmo renderer in your bundle,
and on this repo's own fixture that is the difference between 1 chunk / 8.9 KB
gzipped and 88 chunks / 634 KB. Lazy for your readers; not free for your
dist/.
Opt in if your diagrams change far more often than your site rebuilds:
integrations: [dgmo({ liveLink: { refresh: 'render' } })];The full behaviour, including what each kind of failure does to your build, is in
the remark-dgmo README.
Working reference site
tests/fixture/ is a complete minimal Astro 6 site running this integration. Copy tests/fixture/astro.config.mjs + tests/fixture/src/layouts/Base.astro as a starting template.
git clone https://github.com/diagrammo/astro-dgmo
cd astro-dgmo
pnpm install && pnpm build
cd tests/fixture && pnpm install --no-frozen-lockfile && pnpm exec astro devOpens at http://localhost:4321 with four example diagrams (plain auto, colored tag sequence, showcase mode, per-block override) and a data-theme toggle for verifying the dark/light swap. See tests/fixture/README.md for details.
How CSS is delivered
The shipped remark-dgmo/client.css contains three rules that hide the wrong-mode SVG based on [data-theme="dark"] on <html>. Astro's Vite pipeline inlines the import — a <style> block ends up in <head>, no separate stylesheet file is emitted. The required import 'remark-dgmo/client.css' in a global layout is what triggers that inlining; without it, both light and dark wrappers render at the same time.
A small client script (~600 bytes) is injected via injectScript('page', …). It tightens each diagram's viewBox to its content bounds and binds showcase-mode copy buttons. If your site forbids inline scripts via CSP, ignore this script — diagrams still render, but layout may have extra whitespace and copy buttons won't function.
Custom color-mode selector
The shipped remark-dgmo/client.css keys on [data-theme="dark"]. For Tailwind-style sites that use a .dark class on <html>, don't import that stylesheet — inline these three rules in your own CSS instead:
.dgmo-dark {
display: none;
}
html.dark .dgmo-light {
display: none;
}
html.dark .dgmo-dark {
display: block;
}For other selectors (data-color-scheme="dark", :root[data-mode="dark"], etc.), same three rules with the selector swapped.
How it works
- The Astro integration registers a remark plugin via
astro:config:setupand inline-injects theremark-dgmoclient script viainjectScript('page', …). - The remark plugin walks
.md/.mdxASTs after parse, findingcodenodes whoselang === 'dgmo'. - Each block is rendered to an SVG string by calling
render()from@diagrammo/dgmo— once per theme under defaultcolorMode: 'auto', or once total under'light'/'dark'. Width/height are stripped and aviewBoxis added so the diagram scales responsively. - The original
codenode is replaced with anhtmlnode containing the rendered wrapper(s). - The injected client script tightens viewBoxes after layout and binds copy-button click handlers.
All rendering happens at build time. No diagram source is shipped to the browser unless you enable showcase mode (which inlines a syntax-highlighted copy of the source for display).
Migration
Upgrading from 0.2.x to 0.3.0
Heads up: this release doubles your SVG bytes by default to fix a silent rendering bug on dark/light-toggle sites (Starlight, custom-toggle Astro sites).
v0.2 baked one palette per diagram at build time. If your site supported a dark/light toggle, half your readers saw a mismatched diagram. v0.3 fixes this by rendering each diagram twice (light + dark palettes) and using CSS to show the right one based on [data-theme="dark"] on <html>.
Three paths:
- Do nothing — accept the ~2× SVG bytes per diagram in exchange for correct light/dark behavior. Recommended for Starlight and any site with a color-mode toggle.
- Opt out: set
colorMode: 'light'(or'dark') in the integration options to keep the v0.2 single-render behavior. Recommended only if your site is single-mode. - Use a different selector: if your site signals dark mode via
.darkclass instead of[data-theme="dark"], see "Custom color-mode selector" above.
You must add a CSS import to a global layout — see Quick start.
Class names changed. The rendered HTML class-name prefix changed from astro-dgmo-* to dgmo-* (e.g., astro-dgmo → dgmo). For one minor cycle (v0.3.x) we emit BOTH so existing CSS keeps working. v0.4 drops the legacy aliases. If you have CSS or DOM walkers targeting astro-dgmo-* classes, update them now to the dgmo-* equivalents.
Upgrading to 0.6.0
v0.6 adopts the standard DGMO embed block (via remark-dgmo 0.5): the dgmo-card class is removed, syntax-token classes are renamed to dgmo-tok-*, the source view now sits behind a native <details> (dgmo-source-wrap), and showcase chrome is a hover-revealed icon toolbar (dgmo-toolbar-btn, dgmo-copy, dgmo-open). If you have custom CSS targeting dgmo-card or old token classes, retarget it to the new class names.
No API changes. No breaking changes to fenced-block syntax or per-block options.
License
MIT
