Communitygithub.com

timerise-ai/blog-markdown

AI 代理技能:建立一個基於檔案的多語言 Markdown 部落格 — 按語言分區的文章、透過共享 translationKey 連結的本地化 slug、以 slug 為識別的標籤頁面、相關文章、封面圖、RSS、Sitemap、hreflang、CI 內容驗證器 — 在 Next.js App Router 上實現,無需 CMS

blog-markdown 是什麼?

這個技能提供了一個完整且經過實戰驗證的設計,用於在 Next.js App Router 中建立一個多語言、基於檔案的 Markdown 部落格。核心概念是利用 `translationKey` 而非 slug 來識別文章,這使得不同語言版本的同一篇文章可以有不同的 SEO 友好 slug,同時又能透過 `translationKey` 關聯起來,支援 hreflang、語言切換器、相關文章等功能。技能包含了詳細的規則和注意事項,例如如何處理 YAML 解析錯誤、快取、記憶化、標籤 URL 碰撞,以及如何避免常見陷阱。支援的平台是 Next.js App Router,它透過靜態生成(Static Generation)來運作,並提供了從檔案讀取到 SEO 標籤、RSS、Sitemap 的完整方案,非常適合不想依賴 CMS 的專案。

相容平台~Claude Code~Codex CLI~Cursor
npx skills add timerise-ai/blog-markdown

在你喜歡的 AI 中提問

開啟一個已預先載入此 Agent Skill 的新對話。

說明文件

Markdown 部落格(多語言、標籤化)

一個內容以檔案為核心的部落格,而非資料庫中的紀錄。整個設計圍繞一個核心概念: 一篇文章的身份是其 translationKey,而非其 slug。 Slug 是為了 SEO 而本地化的,每種語言都不同;而 translationKey 才是讓三個檔案成為同一篇文章的關鍵,它驅動了 hreflang、語言切換器、相關文章以及跨語言重定向。只要正確設定這個欄位,其他一切都只是查詢操作。

由實際部署過此模組的工程師撰寫。之前實作經審計的對象是一個多語言、靜態生成的營銷部落格,包含其 Sitemap 和 SEO 表面。以下的事實和規則是內容層套件和建置流程所驗證的;references/provenance.md 中有相應的記錄。

使用時機

  • 內容以 Markdown 形式存放於程式碼庫中,並隨應用程式一起部署
  • 支援多種語言,且每種語言使用不同的 slug
  • 需要標籤頁面、相關文章、摘要或 hreflang
  • 希望整個部落格在建置時靜態生成

不應使用的時機

替代方案使用此技能時機
使用託管的 CMS 作為資料來源直接使用該 CMS 的 SDK;僅保留 references/content-model.md
文件網站/幫助中心(包含分類、側邊欄、搜尋)使用幫助中心技能 — 導航模型不同
單一語言的部落格,少於 10 篇文章直接使用 fs + gray-matter 內嵌;此技能會造成額外開銷
渲染使用者提交的 Markdown使用清潔渲染器;請參閱 references/rendering.md 中的 XSS 說明

架構

content/blog/<locale>/<localized-slug>.md   # frontmatter + body
        |
        v
 parseFrontmatter  --YAML, 若遇到格式錯誤的引號則回退到行解析器
        |
        v
   getAllPosts(locale)  <-- 在生產環境中按語言記憶化
        |
        +--> translationKey ----> alternates / hreflang / 語言切換
        +--> tags -> tag SLUG ---> 標籤頁面(slug 是身份,而非標籤名稱)
        +--> related (EN slugs) -> 相關文章,附帶 EN 備援
        |
        v
  /blog   /blog/[slug]   /blog/tag/[slug]   sitemap.xml   feed.xml

關鍵事實

  1. 關聯只在一處撰寫,即預設語言,並使用預設語言的 slug。 翻譯後的檔案可以省略 related,但仍然能透過 translationKey 解析出正確的相關文章,因此每個翻譯版本都渲染出相同的相關區塊。備援測試對此有驗證。
  2. 標籤的身份是其 slug,而非標籤名稱。 "AI Agents" 和 "AI agents" 會 slug 成相同的 URL。按 slug 分組並比對文章標籤,這樣所有拼寫變體的文章都會出現在同一個標籤頁面上。有兩個測試對此驗證。
  3. gray-matter 在遇到包含原始引號字符的雙引號 YAML 標量時會拋錯 — 翻譯後的摘要中使用的印刷體引號會觸發此問題。如果沒有回退解析器,建置會在該檔案上停止;逐行回退解析器能保證其正常載入。已針對該函式庫驗證,並有測試覆蓋。
  4. gray-matter 會將失敗的解析快取為空結果。 它在解析之前就寫入了快取條目,因此對於一個曾拋錯的檔案,第二次及之後的所有解析都會返回 {} — 沒有錯誤,沒有 frontmatter。始終使用 matter(contents, {}) 呼叫;任何選項物件都會跳出快取。
  5. 每個頁面的載入成本是 O(文章數 x 語言數),除非你進行記憶化。 按語言記憶化,這樣每個內容檔案在建置時只被讀取一次;否則在 generateMetadata 中解析 alternates 會導致 71 倍的檔案讀取放大(根據先前實作測量)。
  6. getPostSlugs 必須過濾 .md 檔案。 這個過濾器可以防止一個不相關的 .DS_Store 檔案被當作 .DS_Store.md 讀取而導致 ENOENT 錯誤。有測試驗證此點。
  7. 標籤頁面沒有跨語言的身份。 標籤是每種語言的自由文字,因此語言切換器在標籤 URL 上必須回退到部落格首頁,而不是建立一個會導致 404 的 URL。

嚴格規則

切勿以 slug 為鍵進行跨語言查詢。 Slug 是故意本地化的。translationKey 才是連接欄位;不同語言間 slug 的匹配只是巧合,不是一種關聯。

切勿讓 getPostBySlug 隱式決定草稿的可見性。 在載入器中過濾草稿;dynamicParams = false 僅僅作為副作用隱藏它們,一旦此標誌改變,它就不再生效。草稿測試會驗證此過濾器。

切勿渲染一個固定的「5 分鐘閱讀」常數。 應根據內容本體計算閱讀時間;只需一次 split 操作,閱讀時間測試會驗證此點。

切勿在讀取時從標籤名稱推導出標籤頁面的 URL,而在渲染時又從 URL 推導出標籤名稱,而不進行碰撞檢查。 僅當每個標籤名稱都能唯一地 slug 化時,這種往返才是無損的。

快速開始

  1. 設定語言合約和 frontmatter 結構 — content-model.md
  2. 建立載入器(記憶化、.md 過濾、回退解析器) — content-loader.md
  3. 建立語言、alternates 和跨語言重定向的連線 — i18n-and-routing.md
  4. 新增標籤分組和標籤頁面 — tags.md
  5. 建立三個路由、中繼資料和 JSON-LD — pages-and-seo.md
  6. 渲染內容本體和封面圖 — rendering.md
  7. 加入驗證腳本並閱讀操作員空白 — operations.md
  8. 運行測試 fixtures 和測試套件 — testing.md

想將此技能移植到現有應用程式中?請先在 adaptation.md 中填寫接縫表 — 這只需十分鐘,可以省去後續重新命名的麻煩。

參考目錄

情境觸發關鍵字參考文件
Frontmatter 欄位、草稿、翻譯鍵、關聯frontmatter, schema, translationKey, draft, related, excerptcontent-model.md
讀取檔案、快取、YAML 失敗、閱讀時間gray-matter, fs, cache, memoize, ENOENT, YAMLException, parsecontent-loader.md
語言、hreflang、alternates、錯誤語言連結i18n, locale, hreflang, alternates, canonical, language switcher, redirecti18n-and-routing.md
標籤 URL、碰撞、稀疏標籤頁面tag, slug, diacritics, collision, tag page, taxonomytags.md
路由、中繼資料、JSON-LD、Sitemap、RSSpage.tsx, generateStaticParams, generateMetadata, dynamicParams, sitemap, RSS, feed, BlogPostingpages-and-seo.md
Markdown 轉 React、程式碼區塊、封面圖react-markdown, remark-gfm, syntax highlighting, cover, motif, accent, XSSrendering.md
驗證內容、建置成本、編輯器工作流程validation, CI check, build time, drafts, authoring, operatoroperations.md
Fixtures 和通過的測試套件test, fixture, vitest, node:test, regression, asserttesting.md
將此技能整合到宿主應用程式:接縫、重新命名、探測adapt, port, host, seam, rename, CMS, integrateadaptation.md
審計記錄:與先前實作相比,更改了、保留了和新增了什麼provenance, deviations, fidelity, audit, ledgerprovenance.md

相關技能