PlantUML in enterprise wikis — Lark / Confluence / Notion three approaches

puml.online

Enterprise docs are dense, easy to search, but rendering “PlantUML source + diagram” inside Lark / Confluence / Notion differs sharply. Below are three real approaches for the most-used wikis.

Why are enterprise wiki diagrams harder?

Personal blogs (Hexo / Hugo) just use a renderer plugin. But enterprise wikis:

  • Multi-author: not everyone can maintain a diagram.
  • Multi-platform: must render on phone / iPad / PC.
  • Permissioning: each wiki section has different visibility.
  • External domain issues: PlantUML via cross-border network in mainland is flaky.
  • Export requirement: regulatory / compliance requires periodic PDF / HTML export.

Below: Lark (Feishu) / Confluence / Notion, separately.

Lark (Feishu) Docs

Lark’s killer feature: built-in PlantUML rendering! Just /plantuml in a code block.

Native support

1
2
3
/plantuml
Alice -> Bob: Hi
Bob --> Alice: Hi back

Top menu Insert → Code block → /plantuml. Lark server auto-renders via PlantUML.

Pros:

  • Zero config — Lark has its own renderer.
  • Auto-synced to wiki home.

Pitfalls:

  • Cross-border on server side: Chinese-Lark uses an internal PlantUML server; occasional render failure (OOM / timeout).
  • Limited themes: only a few built-in themes; custom !theme does NOT take effect.
  • Skin parameters: sometimes ignored by Lark’s server.

Client-side fallback

If server rendering fails, paste this into the page <head> (via Lark’s custom HTML block):

1
2
3
4
5
6
7
8
<script src="https://cdn.jsdelivr.net/npm/plantuml-encoder@1.4.0/lib/puml.min.js"></script>
<script>
document.querySelectorAll('.puml-fallback').forEach(el => {
const code = el.textContent.trim();
const encoded = plantumlEncoder.encode(code);
el.innerHTML = `<img src="data:image/svg+xml,...">`;
});
</script>

In practice, code blocks that the server can’t render fall back to the client, hitting plantuml.com.

Lark “Miaoda” — self-hosted PlantUML app

Lark’s Miaoda (妙搭) is a no-code platform that runs docker containers:

1
2
3
4
# Create an app in Miaoda, port 8080
image: plantuml/plantuml-server
ports:
- 8080:8080

Then in the doc:

1
2
/plantuml-url http://your-miaoda-app.feishu.cn
Alice -> Bob: Hi

Miaoda runs inside the Lark intranet — no cross-border issues, ideal for enterprise.

Confluence (Atlassian)

Confluence has no native PlantUML rendering — community approach is install a plugin or DIY.

Approach A: Confluence PlantUML plugin (commercial)

Search “PlantUML” in Atlassian Marketplace — the “PlantUML for Confluence” paid plugin starts at $5 / month.

After install:

  1. Click + → Other macros → PlantUML Diagram
  2. Put PlantUML code into the macro body parameter
  3. Confluence page renders by calling local Java + plantuml CLI at view time.

Pros: diagrams embedded inline, indexed by search API.
Cons: plugin may bind to an older PlantUML version (8.x/9.x, lagging a year).

Approach B: Self-hosted plantuml-server + macro

The paid plugin is expensive; DIY is possible. In Confluence Data Center (DC):

  1. Deploy plantuml/plantuml-server docker on a Confluence server node
  2. Write a Confluence user macro ({plantumlserver}) that calls the internal API
  3. In Confluence pages use the {plantumlserver} macro to forward the body to internal plantuml
1
2
3
4
5
6
7
8
9
// Snippet of Confluence user macro
public class PlantUMLServerMacro {
@Override
public String execute(...) {
String body = parameters.get("body");
String encoded = plantumlEncoder.encode(body);
return "<img src='http://internal-plantuml:8080/svg/~h" + encoded + "'>";
}
}

Approach C: embedded image (most basic)

The most basic but most reliable approach: render locally, export SVG/PNG, paste into Confluence page.

1
2
3
4
5
6
plantuml -tsvg diagram.puml
# rsync to Confluence attachments
curl -u admin:token -X POST \
-F "file=@diagram.svg" \
-F "comment=PlantUML source diagram" \
$CONFLUENCE/rest/api/latest/attachments

Workflow: source .puml in git, render product .svg in Confluence attachments. Want sync? CI auto-git diff --exit-code:

1
2
plantuml -tsvg docs/diagrams/system.puml
diff docs/diagrams/system.svg $CONF_SVN_SYSTEM_SVG || echo "diagram stale"

Confluence compatibility notes

  • Confluence 7.x disables inline <script> by default — client-side PlantUML needs admin opt-in.
  • Confluence Cloud forces HTTPS — internal plantuml server either gets SSL or sits behind a Confluence reverse proxy.
  • Confluence search by default does NOT index inline SVG content — diagram text is unsearchable; add <title> or alt= to the <img>.

Notion

Notion code blocks render Mermaid, not PlantUML — you must DIY.

Approach A: code block + Mermaid replacement

1
2
3
sequenceDiagram
Alice->>Bob: Hi
Bob-->>Alice: Hi back

If your diagrams are already Mermaid — easy. But Notion does not support PlantUML; either rewrite in Mermaid or add an extension.

Approach B: Notion API + plantuml server

Notion’s webhook is one-way; real “auto-sync diagram” approach:

  1. Place a code block in a Notion page with PlantUML source.
  2. A CI task polls Notion API, fetches the source, renders to SVG.
  3. Upload the SVG back to Notion (API) replacing the image.
1
2
3
4
5
6
7
8
9
# notion_plantuml_sync.py
import requests, base64, urllib.parse

NOTION_TOKEN = "secr...ndef render_puml_to_svg(puml_code):
encoded = plantuml_encoder.encode(puml_code)
r = requests.get(f"https://www.plantuml.com/plantuml/svg/~1{encoded}")
return r.text # raw SVG

# ... Notion API pulls code block, embeds SVG, sends it back

The toolchain is complex but enterprises get used to it.

Approach C: browser extension (clumsy but works)

Browser extension PlantUML Visualizer: detects text/plantuml blocks on the page and renders them automatically.

Pitfall: the extension only works on the local machine; others opening the Notion page see no diagram.

Approach D: embed iframe pointing to puml.online

If your wiki runs on intranet, build a static page with PlantUML rendered; embed <iframe> in Notion:

1
2
3
4
<iframe
src="https://internal-puml.example.com/?code=...puml-encoded..."
width="600" height="300" frameborder="0">
</iframe>

For intranet puml services mind security — don’t let users shove shellcode into the URL.

Three approaches compared

Dimension Lark wiki Confluence Notion
Native PlantUML ✅ (built-in) ❌ plugin / server ❌ DIY
CJK support ✅ (built-in fonts) Plugin-dependent Plan-dependent
Cross-border issues Occasional (CN version) Mainly DC self-host Client-render bypass
Diagram version control Lark has built-in history Confluence page version Notion page version
PDF export ✅ built-in ✅ built-in ❌ print only
Search Lark built-in Full-text + attachment name Only SVG file name

Best-practice picks

Decision rules

  • Lark-primary → use /plantuml code blocks directly; set up Miaoda self-host as fallback.
  • Confluence DC (Data Center) → paid plugin if scale justifies it; otherwise user macro + internal plantuml server.
  • Confluence Cloud → embed image (Approach C) + CI sync.
  • Notion → pick Mermaid or build an internal diagram rendering service; avoid complex solutions.

Universal conventions

Regardless of the wiki:

  1. Separate source + diagram: source (.puml) in git (PR review), diagram in wiki (direct view).
  2. CI validation: every diagram has a CI unit (renders without error + non-empty SVG).
  3. Source block at the end: under the diagram, paste PlantUML source (so others can copy).
  4. Unified CJK font: every diagram skinparam defaultFontName "Noto Sans CJK SC".
  5. Periodically export PDF: regular wiki export to PDF; diagrams survive the format.

Recap

  • Lark: native support, enterprise-first choice.
  • Confluence: paid plugin; fallback is image embed + CI.
  • Notion: hard limit (no PlantUML) — prefer Mermaid or DIY.

Next

  • Title: PlantUML in enterprise wikis — Lark / Confluence / Notion three approaches
  • Author: puml.online
  • Created at : 2026-07-30 11:01:00
  • Updated at : 2026-08-14 21:34:29
  • Link: https://puml.online/blog/plantuml-enterprise-wiki-en/
  • License: This work is licensed under CC BY-NC-SA 4.0.