Astro Content Loader 怎麼用:用 glob() 建立可驗證的本機內容集合
當文章、設定資料與 JSON 都放進 src/content/ 後,最容易混亂的不是讀取 API,而是「哪些檔案真的屬於這個 collection」。Astro 的 Content Loader API 提供 glob(),可把目錄與副檔名的邊界寫在 collection 定義裡,再交由 schema 在建置期驗證。
核心做法是:用 base 固定資料夾、用窄的 pattern 描述檔案類型、讓 schema 驗證 frontmatter;不要用過寬的 glob 把範例或暫存檔一起收進來。
用 base 把 collection 的責任範圍說清楚
glob() 是 Astro 內建的 object loader,支援 Markdown、MDX、Markdoc、JSON、YAML 與 TOML。以下範例只讀取 src/data/notes 裡的 Markdown:
import { defineCollection, z } from 'astro:content';import { glob } from 'astro/loaders';
const notes = defineCollection({ loader: glob({ base: './src/data/notes', pattern: '**/*.md', }), schema: z.object({ title: z.string(), published: z.coerce.date(), }),});
export const collections = { notes };base 是路徑邊界,pattern 則在邊界內篩檔。若集合只該收 Markdown,別寫成 **/*;未來放入圖片、草稿或輔助 JSON 時,建置錯誤才不會變成難以追查的資料型別問題。
ID 不是檔名以外的第二套路徑
預設 ID 由 loader 依 entry 產生。若資料要保留大小寫或要去掉特定副檔名,可用 generateId 明確定義。這個選項適合外部系統 ID 已經存在的 JSON 集合;一般文章 collection 不必先客製化,否則連結與查詢會多一層自行維護的規則。
const authors = defineCollection({ loader: glob({ base: './src/data/authors', pattern: '**/*.json', generateId: ({ entry }) => entry.replace(/\.json$/, ''), }),});retainBody 只在不需要正文時關閉
loader 可用 retainBody: false 不將原始內容保存在 data store。這適合只用 frontmatter 做索引或清單的筆記;如果頁面需要 render Markdown 正文,就保留預設值。不要為了猜測建置效能先關閉它,否則稍後在頁面取正文時才發現資料已不存在。
建置前先做三個檢查
- 在
base建立一個最小範例,確認 pattern 真的包含它。 - 故意少填 schema 必填欄位,確認錯誤能指出正確 entry。
- 執行
pnpm check後再跑完整建置,避免只靠型別提示漏掉 loader 的資料問題。
這個專案既有文章仍可透過 Content Collections 提供給頁面與相關文章計算;若你要處理文章間的連結排序,可再參考 Astro 部落格的自動延伸閱讀。glob() 的工作是定義輸入集合,不是替內容關聯打分數。
參考資料:
回報錯字、失效連結,或告訴我你想看的延伸主題。