@barzhsieh/nuxt-content-mermaid
v1.0.4
Published
A Nuxt module designed for integrating Mermaid with `@nuxt/content`. It automatically converts `mermaid` code blocks in Markdown into responsive chart components, and supports lazy loading and dark/light theme switching.
Maintainers
Readme
nuxt-content-mermaid
專為 Nuxt Content v3 整合 Mermaid 的模組。 能自動將 Markdown 中的 ```mermaid 區塊轉換為響應式的圖表元件,並支援 Lazy Loading 與深色模式切換。
Features
- 自動轉換:解析 Markdown 代碼區塊並替換為
<Mermaid>渲染元件。 - 效能優化:支援 Lazy Loading,僅在元件掛載時載入 Mermaid 核心與資源。
- 主題整合:無縫整合
@nuxtjs/color-mode,自動切換 Light/Dark 對應主題。 - 高度客製:支援自訂渲染元件(Wrapper)、Loading Spinner、錯誤畫面以及 CDN 來源。
- Runtime Config:支援透過環境變數動態覆寫設定。
使用前提
- Nuxt 3.19 以上或 4.1 以上(
nuxt@^3.20.1 || ^4.1.0) @nuxt/content@>=3.5.0
Quick Setup
1. 安裝模組
自動設定(自動寫入 modules):
npx nuxi module add @barzhsieh/nuxt-content-mermaidNuxt CLI 對第三方模組預設會裝到
dependencies。若想放devDependencies,請裝完後移動或改用下方手動安裝。
裝到 devDependencies(需手動加入 modules):
# pnpm
pnpm add -D @barzhsieh/nuxt-content-mermaid
# npm
npm install -D @barzhsieh/nuxt-content-mermaid
# yarn
yarn add -D @barzhsieh/nuxt-content-mermaid2. 配置 nuxt.config.ts
確保模組已加入 modules 清單(若使用 nuxi module add 則可略過):
export default defineNuxtConfig({
modules: ["@barzhsieh/nuxt-content-mermaid", "@nuxt/content"],
});3. 在 Markdown 中使用
在 content/ 目錄下的 .md 檔案中直接撰寫 Mermaid 語法:
# 流程圖範例
```mermaid
graph LR
A[Start] --> B{Is it working?}
B -- Yes --> C[Great!]
B -- No --> D[Debug]
```模組會自動將其轉換為 SVG 圖表。
Configuration
你可以透過 mermaidContent 選項進行全域設定。
// nuxt.config.ts
export default defineNuxtConfig({
mermaidContent: {
enabled: true,
loader: {
importSource:
"https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs",
init: {
securityLevel: "strict",
// 其他傳遞給 mermaid.initialize() 的參數
},
},
theme: {
useColorModeTheme: true,
light: "default",
dark: "dark",
},
components: {
renderer: undefined,
spinner: undefined,
error: undefined,
},
},
});參數說明
Top-level
| 參數 | 類型 | 預設值 | 說明 |
| :-------- | :-------- | :----- | :----------------------------- |
| enabled | boolean | true | 是否啟用模組與轉換邏輯。 |
loader
| 參數 | 類型 | 預設值 | 說明 |
| :-------------------- | :-------------- | :---------------------- | :--------------------------------------------------------- |
| loader.importSource | string | jsDelivr CDN | 指定 Mermaid ESM 的載入來源(支援 CDN 或本地路徑)。 |
| loader.init | MermaidConfig | { startOnLoad: false } | 直接傳遞給 mermaid.initialize 的原始設定。 |
theme
| 參數 | 類型 | 預設值 | 說明 |
| :-------------------------- | :------ | :---------- | :------------------------------------------------------------------------------------------------------ |
| theme.useColorModeTheme | boolean | true | 若安裝了 @nuxtjs/color-mode,是否自動跟隨其主題。 |
| theme.light | string | 'default' | 當 colorMode 為 light 時的主題,也可作為 fallback。 |
| theme.dark | string | 'dark' | 當 colorMode 為 dark 時的主題,也可作為 fallback。 |
components
| 參數 | 類型 | 預設值 | 說明 |
| :----------------------- | :------- | :--------- | :----------------------------------------------------- |
| components.renderer | string | undefined | 指定自訂的 Mermaid 實作元件名稱(見進階用法)。 |
| components.spinner | string | undefined | 指定全域的 Loading 元件名稱。 |
| components.error | string | undefined | 指定全域的錯誤顯示元件名稱,渲染失敗時會使用。 |
Note: 所有設定皆可透過
runtimeConfig.public.mermaidContent在部署時進行覆寫。
Advanced Usage
主題與顏色模式 (Color Mode)
模組會依據以下優先順序決定主題:
- 若
theme.useColorModeTheme: true,且專案有安裝@nuxtjs/color-mode:- 偵測為
dark→ 使用theme.dark - 偵測為
light→ 使用theme.light
- 偵測為
- 否則(color-mode 未安裝或
theme.useColorModeTheme為false):- 優先使用
loader.init.theme。 - 若未提供,依序回退至
theme.light,若沒有設置則會回退至theme.dark。
- 優先使用
自訂渲染元件 (Custom Component)
若需完全接管 Mermaid 的渲染行為(例如:加入外框、ZoomIn/Out 功能),可指定 components.renderer。
在
nuxt.config.ts中指定元件名稱:mermaidContent: { components: { renderer: "MyCustomMermaid", } }在
components/MyCustomMermaid.vue中實作:<script setup lang="ts"> // 你可以在此使用 slot 內容或自行呼叫 useMermaid() 等邏輯 </script> <template> <div class="custom-wrapper border rounded p-4"> <Mermaid> <slot /> </Mermaid> </div> </template>
載入中指示
模組在首次渲染前會使用內建的 spinner,如需替換可在 components.spinner 指定元件名稱;該元件也會以 spinner prop 傳入你的自訂渲染元件,方便直接渲染。
以下是極簡的設定與元件示例:
// nuxt.config.ts
export default defineNuxtConfig({
mermaidContent: {
components: {
renderer: 'MyCustomMermaid',
spinner: 'MySpinner', // 選填:改用自己的全域 Loading 元件
}
}
})<!-- components/MyCustomMermaid.vue -->
<script setup lang="ts">
import { ref, onMounted } from 'vue'
import type { Component } from 'vue'
const props = defineProps<{ spinner: Component | string }>()
const loading = ref(true)
onMounted(() => { loading.value = false })
</script>
<template>
<div class="my-mermaid">
<component v-if="loading" :is="props.spinner" />
<Mermaid v-else>
<slot />
</Mermaid>
</div>
</template>元件使用方式
可以用 <Mermaid> 自己包一個的 Vue 元件 。
例如,你可以同時放入標題、Loading 與錯誤顯示,之後就能在任意模板重複使用:
<!-- WrapperMermaid.vue -->
<template>
<section>
<header v-if="title">{{ title }}</header>
<Mermaid>
<slot>
<pre><code>{{ code }}</code></pre>
</slot>
<template #loading>
<component :is="spinner" v-if="spinner" />
<p v-else>Diagram loading…</p>
</template>
<template #error="{ error, source }">
<p>渲染失敗:{{ error instanceof Error ? error.message : String(error) }}</p>
<pre><code>{{ source }}</code></pre>
</template>
</Mermaid>
</section>
</template><!-- 使用範例 -->
<WrapperMermaid
title="Demo Diagram"
spinner="MySpinner"
>
<pre><code>graph TD; A-->B; B-->C; C-->A</code></pre>
</WrapperMermaid>可依需求調整此模式,把常用的 slot 寫在一個可重用的包裝元件中。
錯誤處理
當 Mermaid 解析或渲染失敗時,<Mermaid> 會觸發 error slot,並可透過 components.error 指定全域錯誤元件。兩者都會拿到錯誤內容與原始 Mermaid 定義,方便除錯。
<Mermaid>
<pre><code>graph TD; A-->B; B-->C; C-->A</code></pre>
<template #error="{ error, source }">
<p>渲染失敗:{{ error instanceof Error ? error.message : String(error) }}</p>
<details>
<summary>查看原始定義</summary>
<pre><code>{{ source }}</code></pre>
</details>
</template>
</Mermaid>若想一次註冊、全域套用自訂錯誤畫面,可在設定中指定元件名稱:
// nuxt.config.ts
export default defineNuxtConfig({
mermaidContent: {
components: {
error: 'MermaidError', // 全域註冊的元件名稱
},
},
})Contribution
pnpm install
pnpm dev:prepare
pnpm dev # Run playground
pnpm test # Run tests