옵시디언에선 보이는데 블로그에선 안 보이던 mermaid 다이어그램

문제 상황

옵시디언에서 글을 쓰고, 다이어그램은 mermaid 코드 블록으로 작성하고 있었다. 옵시디언에서는 문제없이 보였지만, GitHub Pages로 배포한 블로그에서는 다이어그램이 렌더링되지 않고 코드 텍스트만 그대로 표시됐다.

원인은 단순했다. 옵시디언은 mermaid 렌더러를 내장하고 있지만, Jekyll은 빌드 시점에 마크다운을 HTML로 변환할 뿐이다. 이 과정에서 ` ```mermaid ` 코드 펜스는 일반 코드 블록으로 변환된다.

<div class="language-mermaid highlighter-rouge">
  <pre><code>flowchart TD ...</code></pre>
</div>

즉 다이어그램으로 그려져야 할 코드 블록만 HTML에 남고, 이를 실제 그림으로 바꿔 줄 주체가 없었던 것이다. 사용 중인 테마에도 mermaid 라이브러리를 불러오는 코드가 없었다.

해결 방법

mermaid는 브라우저에서 실행되는 JavaScript 라이브러리다. 정의 텍스트를 입력받아 해당 위치에 SVG 다이어그램을 그려 준다. 따라서 페이지가 브라우저에 로드된 뒤 클라이언트에서 렌더링하도록 처리하면 된다.

flowchart LR
    A[마크다운 mermaid 블록] --> B[Jekyll 빌드]
    B --> C[코드 블록 HTML]
    C --> D[브라우저 로드]
    D --> E[mermaid.js 실행]
    E --> F[SVG 다이어그램]

CDN에서 불러오는 방법도 있지만 외부 의존성을 두고 싶지 않아 라이브러리를 저장소에 직접 포함하는 self-host 방식을 선택했다.

  1. mermaid.min.jsassets/js/ 폴더에 추가한다. 이 파일 하나만 있으면 브라우저에서 mermaid 다이어그램을 그릴 수 있다.
  2. 블로그 레이아웃 하단에 스크립트를 추가한다. 이 스크립트는 mermaid 코드 블록이 있는 페이지에서만 mermaid.min.js를 불러오고, 코드 블록을 다이어그램으로 바꿔 준다.
<script>
  (function () {
    var blocks = document.querySelectorAll(".language-mermaid");
    if (!blocks.length) return;

    blocks.forEach(function (block) {
      var pre = document.createElement("pre");
      pre.className = "mermaid";
      pre.textContent = block.textContent.trim();
      block.replaceWith(pre);
    });

    var script = document.createElement("script");
    script.src = "/assets/js/mermaid.min.js";
    script.onload = function () {
      var theme = document.documentElement.getAttribute("data-theme") === "dark" ? "dark" : "default";
      mermaid.initialize({ startOnLoad: false, theme: theme });
      mermaid.run({ querySelector: "pre.mermaid" });
    };
    document.body.appendChild(script);
  })();
</script>

코드 블록의 텍스트를 꺼내 <pre class="mermaid">로 바꾼 뒤 mermaid.run()을 호출하면, mermaid가 해당 요소를 SVG 다이어그램으로 렌더링한다.

결과

배포된 블로그에서도 다이어그램이 정상적으로 렌더링된다.

  • 외부 CDN 의존성 없음 — 라이브러리를 저장소 안에 포함하므로 CDN 장애나 공급망 이슈의 영향을 받지 않는다.
  • 불필요한 로드 없음.language-mermaid 블록이 있는 페이지에서만 라이브러리를 불러오므로, 다이어그램이 없는 글에서는 추가 로드 비용이 없다.

부족한 점

  • mermaid 파일의 크기가 약 3MB로 작지는 않다. 다이어그램이 있는 페이지에서만 불러오긴 하지만, 첫 로드 시 부담이 될 수 있다.
  • 다크/라이트 테마는 처음 화면을 그릴 때의 설정만 반영된다. 테마를 토글하더라도 다이어그램 색상은 새로고침 전까지 바뀌지 않는다.

레퍼런스

댓글