Skip to content

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 branchv4(Quartz 預設分支)
Framework presetNone
Build commandgit fetch --unshallow && npx quartz build
Build output directorypublic
環境變數 NODE_VERSION22

重要: git fetch --unshallow 必須加在 build command 前面——Cloudflare Pages 預設做 shallow clone,會導致 CreatedModifiedDate plugin 的 git 日期抓不到。

Phase 6:自動化更新流程

三種方案依使用情境選擇:

方案適用情境複雜度
A — Obsidian Git Plugin知識庫直接放在 Quartz repo 的 content/最簡單
B — GitHub Actions 跨 Repo 同步知識庫與 Quartz repo 分開管理(必搭 Phase 4 策略 A)中等
C — 單一 Repo,content/ 即 vaultQuartz 專案作為 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 commandgit fetch --unshallow && npx quartz build
Build outputpublic
Cloudflare 環境變數NODE_VERSION=22
知識庫 Repoc892836a/LLM_Knowledge_Bases
Quartz Repoc892836a/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 config

GitHub 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

相關概念

來源