說明中心 — Markdown 文章、搜尋、i18n
說明中心是一個小型靜態網站,只有一個硬性要求:每篇文章都必須可到達——無論是從側邊欄、搜尋,或是從尚未翻譯的語系中進入。由實際推出此模組的工程師撰寫;先前版本的實作是行銷網站的說明中心。以下模組將此要求視為可驗證的屬性:側邊欄顯示每個類別的每一篇文章,搜尋無論輸入為何都能對查詢進行排序,相關連結若無法解析則建置失敗。載入器、搜尋和標籤套件涵蓋了這些;詳細記錄在 references/provenance.md。
使用時機
正在建構或擴充說明中心、文件段落或知識庫,這些內容的 Markdown 檔案存放在儲存庫中,使用 Next.js App Router,可能包含或不包含多語系。
何時不該使用
- 部落格。 帶有日期、作者、封面和本地化 slug 的文章屬於不同的內容模型;請保留主機的部落格模組。
- 從程式碼產生的文件(OpenAPI、TypeDoc)——使用它們的產生器並連結到輸出結果。
- 由 CMS 支援的說明網站,編輯人員在執行時期發佈內容——索引合約仍然適用,但載入器、靜態參數和驗證方式會改變;請參閱 extensions.md 中的 CMS 說明。
- 恰好是 Markdown 的行銷頁面。 重複使用主機的渲染器;此模組是圍繞大量文章建立的導航、搜尋和語系模型。
架構
content/help/<[locale]/><category>/<slug>.md
│ gray-matter + 正規化
▼
getHelpIndex(locale) ── React cache():每個請求解析一次 ──┐
categories · articles (sorted) · byKey · tags · byTag · skipped│
│ │
├─► 頁面:landing / category / tag / article ── 中繼資料、JSON-LD、canonical/hreflang
├─► HelpShell ── toSummary → 導航樹(側邊欄 + 抽屜)
│ ── toSearchDoc → HelpSearch(客戶端,分詞前綴搜尋)
├─► helpSitemapEntries()
└─► validate:help(CI)── 未解析的相關連結、排序平手、錯誤日期、錯誤 slug、標籤漂移
所有內容都從索引讀取。沒有其他元件直接存取檔案系統。
關鍵事實
- 檔案系統即是 schema。 資料夾等於類別,檔案名稱等於 slug,frontmatter 僅是中繼資料。
slug/category在 frontmatter 中會根據路徑進行驗證,永不使用。 - 僅摘要被傳遞到客戶端。
toSummary/toSearchDoc會移除內文;將HelpArticle傳遞給客戶端元件會導致在每個頁面中傳輸整個文件庫。 - 未翻譯的頁面是重複頁面。 它會從預設語言渲染,保持其在導航中的位置,顯示提示,canonical 指向預設語言的 URL,並且不會出現在 hreflang 和 Sitemap 中。
- 運行時期會寬容處理;CI 不會。 錯誤的參照會被捨棄,缺少排序順序的會排在最後——而
validate:help會讓建置失敗,提醒作者。 - 搜尋在客戶端執行,這是刻意為之的設計。 每篇文章約 1 KB,已經為了導航載入頁面中,按鍵即時顯示結果。全文搜尋屬於擴充功能。
硬性規則
絕對不要限制可折疊列表的高度。 使用
max-h-*+overflow-hidden會裁剪任何超出範圍的內容且不回報任何訊息。請使用hidden或真正的可折疊元件,這樣列表才能呈現每個連結,否則就完全不顯示。
絕對不要只依
order排序。 平手時會回退到readdir順序,而這在不同檔案系統之間會有所不同。請先用標題打破平手,再用 slug。
絕對不要在未驗證的情況下解析
related連結。 遺失的參照在頁面上是看不見的;驗證器是作者唯一能得知 slug 已被重新命名的管道。
絕對不要搜尋未修剪的查詢,也絕對不要只搜尋標題。 修剪、分詞、處理變音符號、包含標籤和標題、按欄位排名。
絕對不要在具有 i18n 系統的主機中硬編寫 chrome 字串。 每個字串都透過
HelpStrings處理,這樣頁首、頁尾和提示才能一起切換語系。
絕對不要用拼寫來當作標籤的索引鍵。 大小寫、連字號和複數在不同作者之間會不一致。請用
tagSlug分組,讓所有變體都導向同一個頁面,並讓驗證器回報這些差異。
快速開始
- 填寫 seam 合約並確定類別 ID——adaptation.md。
- 選擇內容佈局並編寫設定——content-model.md。
- 複製載入器和 frontmatter 解析器;立即對實際內容執行驗證器——content-loader.md。
- 將字串和路徑連接至主機的 i18n——i18n.md。
- 加入三個頁面、SEO 輔助函式和 Sitemap 條目——routes.md——然後加入標籤頁面和連結晶片——tags.md。
- 建構殼層、導航樹和抽屜——ui.md——然後在主機的原生元件上建立麵包屑、卡片、列表和渲染器——ui-content.md。
- 加入搜尋及其 hook;將零結果 hook 連接到分析系統——search.md。
- 執行已交付的測試,然後檢查行為合約:最長類別是否完全可達、包含尾隨空格的查詢、包含重音符號的查詢、未翻譯頁面的 canonical URL。
參考目錄
| 情境 | 觸發關鍵字 | 參考文件 |
|---|---|---|
| 將此模組整合到現有應用程式中 | adapt, seam, rename categories, host probe, integrate, dependencies | adaptation.md |
| Frontmatter、資料夾、Slug、驗證 | frontmatter, slug, category, order, related, updatedAt, featured, validate, CI | content-model.md |
| 將檔案讀入索引 | loader, gray-matter, cache, fallback, headings, sort, index, fs | content-loader.md |
| 搜尋框與排名 | search, combobox, ranking, tokenize, diacritics, prefix, keyboard, no results | search.md |
| 標籤、標籤頁面、晶片、標籤雲 | tag, tags, tag page, chip, tag slug, spelling, plural, browse by tag | tags.md |
| 語系、字串、日期、Canonical | i18n, locale, translation, fallback, hreflang, strings, plural, Intl | i18n.md |
| 頁面、中繼資料、JSON-LD、Sitemap | route, page.tsx, generateStaticParams, dynamicParams, notFound, canonical, TechArticle, sitemap | routes.md |
| 殼層、頁首、側邊欄、抽屜 | layout, sidebar, mobile menu, drawer, collapsible, sticky, HelpShell | ui.md |
| 麵包屑、卡片、列表、渲染器、樣式 Hook | breadcrumb, category card, article list, react-markdown, data-help, styling | ui-content.md |
| 超出已交付模組的功能 | full-text, Pagefind, TOC, feedback, git dates, MDX, CMS, redirects | extensions.md |
| 範本為何與先前實作不同 | provenance, audit, ledger, kept deliberately, fixing the earlier implementation | provenance.md |