Docs & Code Guide

Embed diagrams in VitePress: a live architecture view in Vue-parsed Markdown

VitePress compiles every Markdown file into a Vue component, which makes pasting an embed snippet slightly different from pasting it into any other docs generator. Get the Vue template rules right once and the reward is a diagram that follows its source: edit it, and every page showing it updates within minutes, with no rebuild of the site. Here is what VitePress does to the HTML you paste, and the two embed forms that work.

7 min readFor teams whose docs site runs on VitePress

See it as a diagram

Everything below, as a diagram you can edit. Describe yours and see it in seconds.

175/20003 credits left
Try:

No account needed · Editable canvas, not a picture

VitePress parses your pasted HTML as a Vue template

In VitePress, Markdown is first rendered to HTML and then processed as a Vue single file component. Raw HTML in a page is legal, but it is Vue template syntax, not plain HTML. Two consequences matter for embeds. First, double curly braces anywhere in the text are treated as Vue interpolation, so a URL or caption containing them breaks the compile; wrap the offending element in v-pre if you ever hit this. Fenced code blocks are exempt because VitePress wraps them in v-pre automatically.

Second, the Vue compiler is stricter than a browser. Browsers silently repair an unclosed tag; the Vue template compiler fails the build instead. So close the iframe tag explicitly, keep attribute quotes balanced, and the snippet compiles like any other template. No ClientOnly wrapper and no v-if guard is needed: a static img or iframe renders identically during server-side generation and in the browser, so there is nothing to defer to the client.

External images bypass the asset pipeline, which is the point

When a Markdown image points at a relative path, Vite processes it as an asset: the file is hashed, copied into the build output, and frozen at build time. An absolute http or https URL takes the other branch: VitePress leaves it untouched, and each reader fetches the image from the source when the page is viewed.

That untouched branch is what makes a live embed possible. A Datadef project shared public serves a permanent image URL, re-rendered when the diagram changes, with an ETag from the diagram's last edit and a five minute cache lifetime. Edit the diagram and the docs page shows the new version within minutes, without a commit, a CI run, or a redeploy of the VitePress site.

<!-- Live image: absolute URL, so Vite's asset pipeline never touches it -->
![Platform architecture](https://datadef.io/api/embed/my-platform-a1b2c3d4)

<!-- Sized render for a wide layout (params optional) -->
![Platform architecture](https://datadef.io/api/embed/my-platform-a1b2c3d4?width=2400&height=1400&scale=2)

The iframe form when readers need pan and zoom

Because raw HTML is allowed, an interactive embed is one tag. Readers can pan and zoom the actual diagram, which beats a scaled image for column-level lineage or dense service maps. The frame is chrome-less apart from a small attribution link to the full diagram.

<iframe
  src="https://datadef.io/embed/my-platform-a1b2c3d4"
  style="width: 100%; height: 480px; border: none; border-radius: 8px;"
  title="Platform architecture"
></iframe>

Vue template rule

Close the iframe tag explicitly and keep the markup valid. The Vue compiler fails the build on markup a browser would silently repair.

Keeping the diagram itself current

The embed removes the re-export step, not the edit step. Someone still updates the diagram when the architecture changes, and with the VitePress build out of the loop, that edit is the only moving part left. The lightweight loop is manual editing in Datadef. The heavier loop hands the edit to a coding agent: Datadef exposes its diagram tools over MCP, registry name io.datadef/mcp, and Claude Code or Cursor connected to that server can redraw the diagram from what a merge changed. None of this is automatic detection, Datadef never looks at your repository on its own; the redraw happens when your CI job or a teammate invokes the agent. The API key that authorizes an agent is created in settings, on paid plans.

Deciding when that call is worth making is its own question, covered in when to regenerate an architecture diagram. The general pattern is living documentation: the doc follows the source instead of memory.

Where this breaks in VitePress

Both embed forms exist only for projects shared public. Confidential architectures need a different trade: commit a static export into the repo and accept staleness, or keep the diagram out of public docs entirely.

VitePress also has a strong in-repo alternative: Mermaid via a markdown-it plugin keeps small flows in the same commit as the prose, which is genuinely the right call for a ten node flowchart. Generated Mermaid layout struggles past roughly twenty nodes, zone groupings, and column detail, which is where an embedded diagram with a real layout earns its place. The Markdown-file baseline, including GitHub rendering, is covered in embed diagrams in Markdown.

FAQ

How do I embed an iframe in VitePress?

Paste the iframe tag directly into the Markdown file. VitePress allows raw HTML, but it is compiled as a Vue template, so the markup must be valid: close the iframe tag explicitly and avoid double curly braces outside code fences. A static iframe needs no ClientOnly wrapper because it renders identically on server and client.

Does VitePress process external images at build time?

No. Only relative paths go through the Vite asset pipeline, where files are hashed and copied into the build output. An absolute http or https URL is left as-is and fetched by the reader at view time, which is what allows an externally hosted diagram to update without rebuilding the site.

Why did my VitePress build fail after I pasted an embed snippet?

The usual causes are Vue template parsing: an unclosed tag the browser would tolerate but the Vue compiler rejects, or double curly braces in the pasted content being read as Vue interpolation. Close every tag and wrap brace-containing elements in v-pre. Fenced code blocks are already exempt.

Will the VitePress dead-link checker catch a broken diagram embed?

No. The build-time checker validates internal links only; external URLs are never fetched. An embed that starts returning 404, for example because the source project went private, passes the build and shows a broken image in production.

Does an embedded diagram update automatically in VitePress?

The embed follows its source: Datadef serves the image with a five minute cache lifetime, so an edited diagram appears in the docs within minutes without a rebuild. The diagram edit itself is not automatic; a person or an MCP-connected agent has to make it when the architecture changes.