monotux.tech

Adding icons to Mermaid charts

MermaidJS Hugo

This post is part of the Adding MermaidJS Without Any JS series.

Woodpecker CI, Hugo & MermaidJSAdding icons to Mermaid charts

While we are ricing…enhancing this blog with MermaidJS charts, we might as well add icons to said charts as well! This was also surprisingly easy to do, so here we go…

Not every article needs a picture

Not every article needs a picture

As of mermaid-cli version 11.10.1 one can add icon packs when rendering MermaidJS charts! It was implemented in PR954 which provides some details on how to use it, which essentially is just adding below to the mermaid-cli call:

  --iconPacks '@iconify-json/logos' \
  --iconPacksNamesAndUrls "azure#https://raw.githubusercontent.com/NakayamaKento/AzureIcons/refs/heads/main/icons.json"

…and then you can use icons!

architecture-beta
    group api(azure:azure-cloud-shell)[API]

    service db(azure:azure-database-postgresql-server)[Database] in api
    service disk1(azure:azure-fileshares)[Storage] in api
    service disk2(azure:data-box)[Storage] in api
    service server(azure:app-services)[Server] in api

    db:L -- R:server
    disk1:T -- B:server
    disk2:T -- B:db

Above will render like below:

Look at all the icons!

Look at all the icons!

I haven’t found any preview of the icons in the repository I’m using in this example, so it’s always a surprise what comes out. :-) There is, however, an icon gallery at icones.js.org which does not contain this particular set, but many others.

This is my current publish.yaml workflow:

when:
  - event: [push, manual]
    branch: master

steps:
  mermaidcharts:
    image: ghcr.io/mermaid-js/mermaid-cli/mermaid-cli:11.12.0
    commands:
      - |
          #!/bin/sh
          set -o errexit   # abort on nonzero exitstatus
          set -o nounset   # abort on unbound variable
          set -o pipefail  # don't hide errors within pipes

          for md_file in $(grep -l -r mermaid content|grep -E "md$"); do
            echo "Converting $md_file"
            dir=$(dirname $md_file)
            bas=$(basename $md_file)
            cd $dir
            /home/mermaidcli/node_modules/.bin/mmdc \
              --puppeteerConfigFile /puppeteer-config.json \
              -i $bas \
              -o $bas \
              --theme $THEME \
              --backgroundColor $BACKGROUND \
              --outputFormat $OUTPUT_FORMAT \
              --iconPacks '@iconify-json/logos' \
              --iconPacksNamesAndUrls "azure#https://raw.githubusercontent.com/NakayamaKento/AzureIcons/refs/heads/main/icons.json"
            sed -i -E 's|!\[([^]]*)\]\(\./([^ ]+) "([^"]+)"\)|\{\{< figure src="\2" alt="\3" caption="\1" >\}\}|g;s|!\[([^]]*)\]\(\./([^)]*)\)|\{\{< figure src="\2" caption="\1" >\}\}|g' $bas
            cd -
          done

    environment:
      THEME: 'default'
      BACKGROUND: 'transparent'
      OUTPUT_FORMAT: 'svg'

  build:
    image: hugomods/hugo:go-git-0.150.1
    depends_on:
      - mermaidcharts
    commands:
      - hugo --minify
    environment:
      INTERNAL_URL:
        from_secret: internal-url
      HUGO_ENV: 'production'

  compress:
    image: alpine:latest
    depends_on:
      - build
    commands:
      - apk add -q --no-cache findutils brotli gzip zstd
      - |
          find ./public -type f -regex ".*\.\(css\|html\|js\|json\|svg\|xml\)$" \
            -exec brotli -v --best {} \+ \
            -exec gzip -v --best -k {} \+ \
            -exec zstd -v -q {} \+

  flyio:
    image: alpine:latest
    depends_on:
      - compress
    commands:
      - apk add --no-cache -q curl
      - curl -L https://fly.io/install.sh | sh
      - /root/.fly/bin/flyctl deploy
    environment:
      FLY_ACCESS_TOKEN:
        from_secret: flyio-access-token
      FLY_APP:
        from_secret: flyio-app-name
      NO_COLOR: 1