症狀
在 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的原始碼資產一起忽略掉