Render PlantUML from code in Hexo (server-side / client-side)

puml.online

Two ways to put PlantUML diagrams into a Hexo blog — server-side pre-render, or client-side live render.

The question

You have a Hexo blog. You want PlantUML diagrams to show up in your posts. How does the renderer get involved?

There are two camps:

  1. Server-side: at build time, plantuml CLI renders every diagram to SVG, and the HTML embeds the static SVG.
  2. Client-side: the page ships with PlantUML source; the browser asks plantuml.com (or your local plantuml server) to render on demand.

Each has tradeoffs. Let’s go through them.

Server-side pre-render

What you install

  • hexo-renderer-plantuml — a plugin that hooks {% plantuml %} blocks into the build pipeline and calls the plantuml CLI / java jar.
  • Java Runtime (because PlantUML is JVM-friendly).
  • PlantUML jar (the plugin will pull it, or you can ship plantuml.jar yourself).

Config

_config.yml:

1
2
3
4
plantuml:
render: plantuml
syntax: ```plantuml
inline: true

How it works in a post

1
2
3
4
5
6
7
8
This is the diagram:

{% plantuml %}
Alice -> Bob: hi
Bob --> Alice: hi back
{% endplantuml %}

And the next paragraph...

The plugin intercepts that block, calls plantuml, embeds the SVG.

Pros

  • Static output. The HTML is finalised. No JS runtime needed.
  • SEO. Search engines see the SVG inline as text plus real alt text.
  • Offline build. As long as your build machine has Java + PlantUML, no network is needed.

Cons

  • Slower build. Each diagram means a JVM startup + render — for a blog with hundreds of diagrams, builds can take minutes.
  • Local Java dependency. CI machines need to install JRE.
  • Plugin version skew between hexo and PlantUML CLI.

Client-side live render

What you install

  • a JS encoder library: plantuml-encoder (npm) or any URL-encoder equivalent.
  • optionally a self-hosted plantuml server behind the GFW.

How it works in a post

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<script src="https://cdn.jsdelivr.net/npm/plantuml-encoder@1.4.0/lib/puml.min.js"></script>

<div class="uml-block">
Alice -> Bob: hi
Bob --> Alice: hi back
</div>

<script>
document.querySelectorAll('.uml-block').forEach(el => {
const code = el.textContent.trim();
const encoded = plantumlEncoder.encode(code);
el.innerHTML = `<img alt="" src="https://www.plantuml.com/plantuml/svg/~1${encoded}">`;
});
</script>

Pros

  • Fast build. No Java, no rendering — just text in HTML.
  • No CI dependencies.

Cons

  • Depends on plantuml.com. If the page is rendered client-side, every reader must fetch from plantuml.com. That’s slow in mainland China, occasionally blocked, also a privacy / availability concern.
  • First-paint delay. The diagram appears after the JS bundle and the URL round-trip.
  • No offline. Lose network, lose diagrams.

Which to choose?

Scenario Recommend
Documentation blog, technical SEO Server-side
Personal blog, dozens of diagrams Client-side
Audit / compliance / GDPR-sensitive Server-side (no third-party render)
Heavy CJK diagrams Client-side (font friendly)
Build machine has no Java Client-side
Build machine has Java + wants speed Server-side

In practice — a hybrid

Many production setups use both:

  • Develop locally with client-side (live edit, fast iteration).
  • Publish via server-side (static SVG, deterministic output).
  • A pre-deploy script that runs locally via plantuml CLI takes any unrendered <script type="text/plantuml"> blocks and emits <img>-rendered SVG.

If you want offline, you can even run a tiny plantuml server with docker run -d -p 8080:8080 plantuml/plantuml-server, then point your plantumlEncoder to that URL instead of plantuml.com.

Recap

  • Server-side = static, fast read, slow build.
  • Client-side = fast build, slower read, depends on third-party.
  • Hybrid = real-world compromise; keep options open.

Next

  • Title: Render PlantUML from code in Hexo (server-side / client-side)
  • Author: puml.online
  • Created at : 2026-07-29 16:16:00
  • Updated at : 2026-08-14 21:34:29
  • Link: https://puml.online/blog/plantuml-from-code-en/
  • License: This work is licensed under CC BY-NC-SA 4.0.