症狀

在 markdown 寫 [HNSW](/algo/ai-era/hnsw-viz.html),Quartz build 後把它轉成 .../algo/ai-era/hnsw-viz(去掉 .html)。建置產物 58-ai-era-algorithms.html 裡的連結 render 成 ../../../algo/ai-era/hnsw-viz。但 astro 產生的實體檔是 hnsw-viz.html。擔心:這 56 個 viz 連結在生產環境會不會全變死連結?

原因

Quartz 對所有內部連結一律去 .html,這跟它自己的頁面連結是同一套(Quartz emit X.html 但彼此連 X)。它的內部連結解析假設的是 clean-URL 部署環境。

而 terryyaowork.cc 用 Cloudflare Pages,clean-URL 預設開啟:

  • 請求 /foo(無副檔名)→ 服務 foo.html
  • 請求 /foo.html → 308 導向 /foo

這是部署層行為,套用到整包 public/,不分來源(Quartz 頁 or astro 靜態頁)。

修法

不用改 markdown。線上實測:/algo/datastructures/linked-list-viz → 200;...-viz.html → 308。所以 Quartz 去 .html 的行為在 Cloudflare 上剛好對,靜態 astro viz 檔跟 Quartz 自己的頁完全同構。

怎麼預防再次發生

  • 混合 Quartz + 外部靜態頁(astro/其他)時,跨系統連結寫不寫 .html 都行,Quartz 會統一成無副檔名;別為此糾結。
  • 真正要驗的是「部署層有沒有 clean-URL」——feature 分支上驗不了,要 deploy preview 或線上 curl:/x→200 且 /x.html→308/200 就是通的。
  • 反例警惕:若換成不做 clean-URL 的靜態 host(純 nginx 未設 try_files),這套會全斷——換 host 前先驗這個行為。

相關主題

  • 同樣在搬 viz 資產時會碰到的坑:.gitignore 裡沒錨點的 public 規則,把 astro-app/public 的原始碼資產一起忽略掉