Appearance
Quartz + Cloudflare Pages — Obsidian 知識庫線上化 SOP
將本地 Obsidian 知識庫透過 Quartz 4 建成靜態網站,部署到 Cloudflare Pages,每次 git push 自動重新 build。
概述
Quartz 4 是一個將 Markdown 知識庫(尤其是 Obsidian vault)轉換為靜態網站的框架,原生支援 [[wikilinks]]、frontmatter tags、Graph View 等 Obsidian 功能。Cloudflare Pages 提供免費的靜態網站托管,並在偵測到 GitHub repo 變更時自動觸發 build。
整體架構:
[Obsidian 編輯] → [git push] → [GitHub Repo]
→ [Cloudflare Pages 偵測] → [npx quartz build]
→ [靜態 HTML 上線]全程不需要自己架 server,只需維護 git push 流程。
核心內容
Phase 1:建立 Quartz 專案
Quartz 有自己的 repo 結構(獨立於 vault),clone 後用 npx quartz create 初始化。
初始化選項(核心設定):
- 初始化內容:選「Empty Quartz」(之後手動放入內容)
- 連結解析方式:選「Treat links as shortest path」(與 Obsidian 預設行為一致)
知識庫內容的三種接入方式
Quartz 讀取 content/ 資料夾內的 Markdown 檔案。接入方式的選擇影響部署策略:
| 方案 | 適用情境 | 注意事項 |
|---|---|---|
| A — Symlink | 僅本機預覽 | Cloudflare Pages 雲端 build 時 symlink 斷裂,不可用於部署 |
| B — 直接複製 | CI/CD 部署 | 在 build 前執行 cp -r wiki/* content/ |
| C — Git Submodule | 知識庫與 Quartz repo 分開管理 | 需設定 submodule 路徑解析 |
Phase 2:quartz.config.ts 關鍵設定
| 設定項 | 說明 |
|---|---|
locale: "zh-TW" | 讓日期顯示為中文格式、UI 文字中文化 |
baseUrl | 部署後替換為實際 .pages.dev 或自訂域名 |
ignorePatterns | 排除 templates/、private/、derived/ 等不需發布的子資料夾 |
ObsidianFlavoredMarkdown | 核心 plugin,解析 [[wikilinks]]、callouts、highlights |
CreatedModifiedDate | 優先從 frontmatter 的 建立日期/最後更新 讀取日期 |
markdownLinkResolution: "shortest" | 最短路徑解析,與 Obsidian 預設一致 |
Phase 3:本機預覽確認 checklist
bash
npx quartz build --serve確認事項:
- [ ] 首頁(
index.md)正確顯示 - [ ]
[[wikilinks]]能正確跳轉 - [ ] 圖片正常載入
- [ ] Tags 頁面有內容
- [ ] 中文字體正常渲染
- [ ] Graph View 顯示連結關係
Phase 5:Cloudflare Pages Build 設定
| 欄位 | 值 |
|---|---|
| Production branch | v4(Quartz 預設分支) |
| Framework preset | None |
| Build command | git fetch --unshallow && npx quartz build |
| Build output directory | public |
環境變數 NODE_VERSION | 22 |
重要:
git fetch --unshallow必須加在 build command 前面——Cloudflare Pages 預設做 shallow clone,會導致CreatedModifiedDateplugin 的 git 日期抓不到。
Phase 6:自動化更新流程
三種方案依使用情境選擇:
| 方案 | 適用情境 | 複雜度 |
|---|---|---|
| A — Obsidian Git Plugin | 知識庫直接放在 Quartz repo 的 content/ | 最簡單 |
| B — GitHub Actions 跨 Repo 同步 | 知識庫與 Quartz repo 分開管理(必搭 Phase 4 策略 A) | 中等 |
| C — 單一 Repo,content/ 即 vault | Quartz 專案作為 Obsidian vault root | 最精簡 |
關鍵要點
git fetch --unshallow是 Cloudflare Pages build 的必要步驟,否則 git 日期功能失效NODE_VERSION=22必須設定,Quartz 4 要求 Node >= 22- Symlink 方案僅適合本機預覽,部署環境一律使用複製或 Git Submodule
- 知識庫 repo 與 Quartz repo 分開管理時,須搭配 GitHub Actions 跨 repo 同步才能觸發自動 build
- Obsidian vault 路徑應指向
content/(若採用方案 C),.obsidian/需加入ignorePatterns
實際應用
- 將本知識庫(
LLM_Knowledge_Bases)發布為公開可搜尋的技術文件網站 - 搭配 Cloudflare Tunnel 可實現更彈性的 DNS 與 SSL 設定
部署設定參考
以下為實際部署時使用的完整設定,供日後查詢與複製使用。
環境參數
| 項目 | 值 |
|---|---|
| Node.js 版本 | >= 22 |
| npm 版本 | >= 10.9.2 |
| Quartz 分支 | v4 |
| Build command | git fetch --unshallow && npx quartz build |
| Build output | public |
| Cloudflare 環境變數 | NODE_VERSION=22 |
| 知識庫 Repo | c892836a/LLM_Knowledge_Bases |
| Quartz Repo | c892836a/quartz-site |
quartz.config.ts(完整設定)
typescript
import { QuartzConfig } from "./quartz/cfg"
import * as Plugin from "./quartz/plugins"
const config: QuartzConfig = {
configuration: {
pageTitle: "LLM 知識庫",
pageTitleSuffix: "",
enableSPA: true,
enablePopovers: true,
analytics: null,
locale: "zh-TW",
baseUrl: "your-site.pages.dev", // ← 部署後替換為實際域名
ignorePatterns: [
"templates",
"private",
".obsidian",
],
defaultDateType: "modified",
theme: {
fontOrigin: "googleFonts",
cdnCaching: true,
typography: {
header: "Noto Sans TC",
body: "Noto Sans TC",
code: "JetBrains Mono",
},
colors: {
lightMode: {
light: "#faf8f8",
lightgray: "#e5e5e5",
gray: "#b8b8b8",
darkgray: "#4e4e4e",
dark: "#2b2b2b",
secondary: "#284b63",
tertiary: "#84a59d",
highlight: "rgba(143, 159, 169, 0.15)",
textHighlight: "#fff23688",
},
darkMode: {
light: "#161618",
lightgray: "#393639",
gray: "#646464",
darkgray: "#d4d4d4",
dark: "#ebebec",
secondary: "#7b97aa",
tertiary: "#84a59d",
highlight: "rgba(143, 159, 169, 0.15)",
textHighlight: "#fff23688",
},
},
},
},
plugins: {
transformers: [
Plugin.FrontMatter(),
Plugin.CreatedModifiedDate({
priority: ["frontmatter", "git", "filesystem"],
}),
Plugin.SyntaxHighlighting({
theme: {
light: "github-light",
dark: "github-dark",
},
keepBackground: false,
}),
Plugin.ObsidianFlavoredMarkdown({ enableInHtmlBlock: false }),
Plugin.GitHubFlavoredMarkdown(),
Plugin.TableOfContents(),
Plugin.CrawlLinks({ markdownLinkResolution: "shortest" }),
Plugin.Description(),
Plugin.Latex({ renderEngine: "katex" }),
],
filters: [
Plugin.RemoveDrafts(),
],
emitters: [
Plugin.AliasRedirects(),
Plugin.ComponentResources(),
Plugin.ContentPage(),
Plugin.FolderPage(),
Plugin.TagPage(),
Plugin.ContentIndex({
enableSiteMap: true,
enableRSSFeed: true,
}),
Plugin.Assets(),
Plugin.Static(),
Plugin.Favicon(),
Plugin.NotFoundPage(),
Plugin.CustomOgImages(),
],
},
}
export default configGitHub Actions:跨 Repo 同步(方案 B)
在知識庫 repo 建立 .github/workflows/sync-to-quartz.yml:
yaml
name: Sync wiki to Quartz site
on:
push:
branches: [main]
paths:
- 'wiki/**' # 只在 wiki 內容變動時觸發
jobs:
sync:
runs-on: ubuntu-latest
steps:
- name: Checkout knowledge base
uses: actions/checkout@v4
with:
path: kb
- name: Checkout Quartz site
uses: actions/checkout@v4
with:
repository: c892836a/quartz-site
token: ${{ secrets.QUARTZ_PAT }} # 需建立 Personal Access Token
path: quartz
ref: v4
fetch-depth: 0
- name: Sync content
run: |
rm -rf quartz/content/*
cp -r kb/wiki/* quartz/content/
- name: Commit and push
run: |
cd quartz
git config user.name "GitHub Actions"
git config user.email "actions@github.com"
git add -A
git diff --staged --quiet || git commit -m "sync: update wiki content $(date +%Y-%m-%d)"
git push前置需求: 在 GitHub → Settings → Secrets 新增
QUARTZ_PAT(Personal Access Token,需 repo 寫入權限)。
Obsidian Git Plugin 設定(方案 A)
Auto pull interval: 10 minutes
Auto push interval: 10 minutes
Auto commit message: vault backup: {{date}}操作指令
bash
# 建立 Quartz 專案
git clone https://github.com/jackyzha0/quartz.git quartz-site
cd quartz-site
npm i
npx quartz create
# 本機預覽(修改後自動 hot-reload)
npx quartz build --serve
# 將知識庫內容複製進 content/(部署前執行)
cp -r /path/to/LLM_Knowledge_Bases/wiki/* content/疑難排解
| 問題 | 解法 |
|---|---|
| Build 失敗:Node 版本不夠 | 確認 Cloudflare Pages 環境變數設有 NODE_VERSION=22 |
| 中文檔名 404 | 在 frontmatter 手動指定 ASCII slug:slug: my-article-slug |
| wikilinks 斷裂 | 確認 CrawlLinks plugin 的 markdownLinkResolution 設為 "shortest" |
| 圖片不顯示 | 確認圖片路徑在 content/ 內可達,Quartz 支援 ![[image.png]] 語法 |
| git 日期不正確 | 確認 build command 包含 git fetch --unshallow |
相關概念
- Cloudflare Tunnel x Synology NAS 架構指南 — Cloudflare 服務的另一種應用:零 port 開放的 NAS 外部存取