跳至主要內容

開發紀錄

文章目錄應該從正文 heading 產生

以本站文章版型為例,說明如何從渲染後的 heading 建立目錄,讓標題、順序與錨點共用來源,並分開處理手機抽屜、無 JavaScript 閱讀與段落指示。

林予晴
發布
  • 內容工程
  • Astro
  • Markdown
  • 文章目錄

改完文章的一個段落標題,還要再去修改旁邊的目錄,這就是兩份結構開始走散的地方。標題文字可能已經不同,段落順序可能交換了,目錄卻還連向原來的位置。

本站的文章目錄不另外寫一份清單,而是取用 Markdown 渲染後的 heading 資料。正文決定有哪些段落,目錄只把其中適合導覽的部分呈現出來。

這個做法減少的是維護兩份結構的工作,不代表文章因此就比較好讀。標題是否清楚、段落有沒有合理順序,仍然要由寫作與校稿處理。

先有正文,再決定哪些標題進目錄

本站文章標題來自 frontmatter,版型會把它輸出成主要 h1;Markdown 正文從 h2 開始。文章查詢也會檢查正文是否混入 h1,避免版型標題和正文各自建立一個頂層標題。

文章版型渲染內容後,從 heading 資料中選出 depth === 2 的項目,作為目前的目錄。

因此,作者不用再填另一個 toc 欄位,也不用手動寫出每個章節的連結。調整正文的 h2 文字或順序後,下次渲染得到的目錄會跟著使用新的資料。

這是一個刻意收斂的規則。本站目前只把主要章節放進目錄,不把所有 h3、h4 都展開成多層清單。它比較適合目前的文章結構;若未來有長篇教學,需要讀者直接定位到子步驟,再考慮巢狀目錄。

錨點跟著渲染結果,不自己猜

Astro 的 render() 可回傳內容元件與 heading 陣列;heading 提供 depth、slug 和 text 等資料。[3] 本站目錄取用其中的 text 作為連結文字,並把 slug 組成 #... 的目標。

下面是現有資料流的簡化示意,不是另一套需要作者手動維護的設定:

Markdown 的段落標題
        ↓
內容渲染產生 heading 資料
        ↓
取出 h2 的文字、順序與 slug
        ↓
目錄連結指向正文的 heading ID

我不會在目錄端另做一套「把中文字轉成網址」的函式。標點、英文大小寫或重複標題的處理應跟正文渲染使用的識別字一致;自己再算一遍,反而可能得到不同目標。

這裡也有維護限制:文章標題改寫後,heading ID 可能跟著變。若有人保存了舊的段落連結,自動目錄不會替舊錨點維持相容性。需要長期穩定引用的章節,仍得另訂錨點策略,不能把文章的 stable ID 與段落錨點當成同一件事。

桌面與手機共用結構,呈現方式可以不同

目前桌面版把目錄放在正文旁的側欄,手機版則使用可開啟的 Drawer。兩邊傳入的是同一份主要 heading 清單,也共用目錄元件。

這讓桌面與手機不會因為各自手寫內容,而出現一邊漏掉章節、另一邊仍顯示舊標題的情況。共用的是段落結構,不是要求兩種螢幕使用完全相同的布局。

文章沒有主要 heading 時,目錄相關區塊不會輸出。目前的規則是清單有項目就顯示,並沒有另外實作「只有兩個標題就隱藏」之類的數量門檻。若之後要調整,應明確改顯示條件,而不是在文章裡描述一個尚未存在的行為。

沒有腳本時,仍有正文和連結

目錄連結在 HTML 中已有真實的段落目標。桌面目錄不需要等腳本執行後才產生;手機版也另外提供 noscript 清單,讓沒有 JavaScript 的讀者仍能使用原生連結。

這不表示手機抽屜本身在無腳本時照常運作。它的開關是一種互動控制;noscript 清單則是另一個閱讀入口。把兩者分開,才不會把「正文可以閱讀」誤寫成「所有動態控制都不需要腳本」。

腳本啟用時,本站還會補上目前段落的指示、目錄項目的 aria-current,以及點選手機目錄後關閉抽屜的動作。捲動效果會依 reduced-motion 設定選擇平滑或直接移動。

這些增強使用正文裡實際存在的 h2[id] 與目錄連結目標,並不另存一份章節名稱。

自動產生不代表可以略過檢查

目錄從 heading 產生,只能減少手寫不同步的風險。作者仍可能寫出「其他」「補充」這類不容易辨識的標題,也可能把一個小提醒提升成主章節,讓目錄變得冗長。

我會先讀目錄能不能交代文章的閱讀順序,再檢查生成結果:

  • 目錄文字與正文主要標題是否一致?
  • 每個連結是否找到對應的 heading ID?
  • 桌面、手機與無腳本清單是否使用相同的章節集合?
  • 沒有主要 heading 時,是否留下無用途的目錄容器?

改完版型後,還要操作實際頁面,檢查點擊是否定位、手機抽屜是否關閉、固定導覽是否遮住標題,以及目前段落的指示是否合理。資料一致並不等於閱讀位置和視覺都已驗收。

讓文章結構只有一個修改入口

這個設計讓文章校稿回到正文。若目錄看起來不清楚,我會先改段落標題和順序,而不是只在側欄換一組比較漂亮的名稱。

因為讀者點進章節後,看到的仍是正文。目錄可以縮短尋找內容的路徑,卻不能替正文另寫一份更好看的結構,掩蓋兩邊實際不同。

紀錄範圍

本文描述本站文章版型的 heading 過濾、目錄元件、手機 Drawer、無 JavaScript 清單與瀏覽器腳本責任。它沒有宣稱目前已有多層目錄、固定段落錨點契約、閱讀成效研究或所有裝置驗收。文章身份與多語路由屬於不同責任,不由目錄清單決定。

Sources

[3] https://docs.astro.build/en/reference/modules/astro-content