Embedding PlantUML in Confluence / Jira / Notion

puml.online

The team wiki is the biggest consumer of PlantUML diagrams. This is the field guide for getting .puml files rendered into clickable SVG inside Confluence / Jira / Notion, including the self-hosted plantuml server gotchas behind corporate firewalls.

Why wiki integration matters

PlantUML source is reviewable in git, but reviewers don’t live in git. 90% of diagram reading happens in Confluence / Jira / Notion pages. If the wiki only shows PNG screenshots, the diagram version drifts from the code: the design changes on Monday, the wiki still shows March.

The ideal chain: *.puml source in git → CI renders to SVG → auto-push back to wiki → wiki pages always show the latest version.

Confluence: three options

Option A: PlantUML Macro plugin (Data Center ships one)

Confluence Data Center comes with a PlantUML plugin out of the marketplace. Syntax is the same as GitLab/GitHub:

1
2
3
4
@startuml
Alice -> Bob: ping
Bob --> Alice: pong
@enduml

Pros: zero config, WYSIWYG.

Cons:

  • Defaults to https://www.plantuml.com/plantuml (public server) — every diagram leaves the company
  • Corporate intranet can’t reach plantuml.com → renders as red error box
  • No version control; who changed the puml is invisible

Fix: admin changes the PlantUML server URL to self-hosted:

1
2
Confluence Admin → Add-ons → PlantUML → Server URL
http://plantuml.internal.company.com:8080

Option B: !include from Confluence attachment

1
2
3
@startuml
!include https://confluence.internal.company.com/download/attachments/123456/sequence.puml
@enduml

Upload sequence.puml as an attachment on a Confluence page, then !include from any page that needs it. Single source of truth: edit one file, every page updates.

Option C: CI renders + uploads images

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# .github/workflows/wiki-sync.yml
name: wiki-sync
on:
push:
paths: [docs/diagrams/**/*.puml]
jobs:
render:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: |
docker run --rm -v $PWD:/data plantuml/plantuml \
-tsvg docs/diagrams/**/*.puml
- name: upload to confluence
run: |
for f in docs/diagrams/*.svg; do
curl -u "$USER:$TOKEN" -X POST \
-F "file=@$f" \
-F "comment=auto-sync from git $GITHUB_SHA" \
"https://confluence.internal.company.com/rest/api/content/123456/child/attachment"
done

Jira specifics

You paste diagrams into Jira tickets not for documentation but so that PR comments and design reviews can reference a stable image.

The most reliable pattern: write PlantUML directly in the ticket description, plus a plantuml.com/plantuml URL:

1
2
3
4
5
6
7
8
9
[plantuml]
----
@startuml
participant User
participant API
User -> API: POST /login
API --> User: 200 OK
@enduml
----

Jira Cloud renders {plantuml} macros natively when enabled.

Notion: two paths

Notion has no native PlantUML support — only code blocks.

Option A: embed pre-rendered SVG

Upload the SVG to a Notion file block. Notion shows it as a vector image. It’s frozen: editing the .puml means re-uploading.

Option B: Notion API auto-sync

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import requests
NOTION_TOKEN = "secr..."
PAGE_ID = "..."

svg_path = "docs/diagrams/login-flow.svg"
r = requests.patch(
f"https://api.notion.com/v1/blocks/{PAGE_ID}/children",
headers={"Authorization": f"Bearer {NOTION_TOKEN}",
"Notion-Version": "2022-06-28"},
json={
"children": [{
"object": "block",
"type": "image",
"image": {"type": "external",
"external": {"url": f"https://github.com/your-org/repo/raw/main/docs/diagrams/login-flow.svg"}}
}]
})

Security and audit trade-offs

Approach Data flow Compliance risk Freshness
plantuml.com public server diagram → third party high (architecture, accounts, IPs in the diagram) instant
Self-hosted plantuml server internal network low instant
CI render + image upload diagram → wiki (already audited) low 1-2 min lag
Manual screenshot never leaves low constantly stale

Rule of thumb: any diagram that contains architecture, accounts, or IPs must never go through plantuml.com. A self-hosted plantuml server has tiny memory footprint (<100MB) and is one Docker line:

1
2
3
docker run -d --name plantuml -p 8080:8080 \
-e PLANTUML_SECURITY_PROFILE=strict \
plantuml/plantuml-server:tomcat

PLANTUML_SECURITY_PROFILE=strict disables !include remote URLs to prevent SSRF.

Common pitfalls

  • Confluence PlantUML macro shows red box: intranet can’t reach plantuml.com. Change the server URL.
  • Jira Cloud {plantuml} macro doesn’t render: Jira Cloud disables external macros by default; admin must enable under “Manage apps”.
  • Notion SVG renders blurry: Notion sometimes force-zooms SVGs; export with width=100% so the SVG itself is responsive.
  • CI render silently fails: the wiki keeps showing the last successful image. Monitor the render artifact count in CI; fail the job when it drops.
  • Title: Embedding PlantUML in Confluence / Jira / Notion
  • Author: puml.online
  • Created at : 2026-07-30 16:30:00
  • Updated at : 2026-08-14 21:34:29
  • Link: https://puml.online/blog/plantuml-confluence-jira-notion-en/
  • License: This work is licensed under CC BY-NC-SA 4.0.