載入器 API
將內容來源轉換為統一的介面
它的用途是什麼?
loader() 提供一個介面,讓 Fumadocs 能與各種內容來源整合。
- 產生頁面 slug 與頁面樹。
- 為每個頁面指派 URL。
- 提供實用的工具函式,方便您操作內容。
重要須知
loader()是伺服器端 API,既不是建置時期的魔法,也不是可在瀏覽器中使用的 API。- 它採用記憶體內儲存,檔案由您的內容來源傳入。
使用方式
您可以搭配 Fumadocs MDX 等內容來源使用,詳情請參閱 source。
import { loader } from 'fumadocs-core/source';
import { docs } from 'collections/server';
export const source = loader({
source: docs.toFumadocsSource(),
baseUrl: '/docs',
});URL
您可以覆寫基礎 URL,或指定一個函式來產生每個頁面的 URL。
import { loader } from 'fumadocs-core/source';
loader({
baseUrl: '/docs',
// 或者您也可以使用函式自訂
url(slugs, locale) {
if (locale) return '/' + [locale, 'docs', ...slugs].join('/');
return '/' + ['docs', ...slugs].join('/');
},
});Slugs
定義自訂函式,用來根據頁面檔案產生 slug。
import { loader } from 'fumadocs-core/source';
loader({
slugs(file, next) {
console.log(file.path, file.data);
// 您可以透過 `next()` 在預設 slug 的基礎上擴充
if (file.path.startsWith('blog/')) return ['blog', ...next()];
// 或回傳 `undefined` 以改用預設值
return ['my', 'slug'];
},
});圖示
載入頁面與 meta 檔案中指定的 icon 屬性。
import { loader } from 'fumadocs-core/source';
import { icons } from 'lucide-react';
import { createElement } from 'react';
loader({
icon(icon) {
if (!icon) {
// 您可以設定預設圖示
return;
}
if (icon in icons) return createElement(icons[icon as keyof typeof icons]);
},
});I18n
請將 i18n 設定傳入載入器。
import { i18n } from '@/lib/i18n';
import { loader } from 'fumadocs-core/source';
export const source = loader({
i18n,
});啟用 i18n 後,載入器會為每個語系產生一個頁面樹。
若某個頁面缺少翻譯,則會改用 fallbackLanguage 作為備用語系。
輸出
它會輸出一個內容載入器實例。
取得頁面
依據 slugs 取得頁面。
import { source } from '@/lib/source';
source.getPage(['slug', 'of', 'page']);
// 使用 i18n 時
source.getPage(['slug', 'of', 'page'], 'locale');自訂 Props
您可以將 props 傳入頁面內容,例如讀者所選的版本。內容會透過 props 讀取這些值,用法與路徑參數相同:
import { source } from '@/lib/source';
const page = source.getPage(['slug', 'of', 'page'], {
props: { version: 'v2' },
// 使用 i18n 時
language: 'locale',
});頁面資料 (包括內容與目錄) 是根據這些 props 產生的。MDX 元件也屬於 props;若希望處理後的 Markdown 能算繪出您的元件,請將它們傳入:
import { getMDXComponents } from '@/components/mdx';
const page = source.getPage(['slug', 'of', 'page'], {
props: { components: getMDXComponents() },
});
const markdown = await page.data.getText('processed');小提醒
搜尋與 LLM 路由是透過 getPages() 讀取頁面,而這些頁面只帶有路徑參數。若要讓搜尋或 LLM 看到某個變體,該變體就必須是路徑參數。
取得頁面
取得指定語系下可用的頁面清單。
import { source } from '@/lib/source';
// 取得所有語系的頁面
source.getPages();
// 取得特定語系的頁面
source.getPages('locale');頁面樹
import { source } from '@/lib/source';
// 未使用 i18n
source.getPageTree();
// 使用 i18n
source.getPageTree('locale');從節點取得
頁面樹的節點會保留指向其原始檔案路徑的參照。 您可以透過樹狀節點找到對應的原始頁面或 meta 檔案。
import { source } from '@/lib/source';
source.getNodePage(pageNode);
source.getNodeMeta(folderNode);參數
產生每個頁面的路徑參數,以便預先算繪頁面。
產生的參數名稱為 slug: string[] 與 lang: string (僅限 i18n) 。
import { source } from '@/lib/source';
export function generateStaticParams() {
return source.generateParams();
}React Router 與 TanStack Start 是依 URL 進行預先算繪,因此請改為列出 source.getPages() 各頁面的 url。
語言項目
取得所有可用的語言及其對應頁面。
import { source } from '@/lib/source';
// 語言 -> 頁面
const entries = source.getLanguages();用戶端 API
載入器 API 最適合在 RSC 環境中使用,因為 RSC 允許跨越伺服器與用戶端的邊界傳遞 JSX 節點。
在非 RSC 環境中,載入器 API 則提供一個輕量的序列化層。
import { source } from '@/lib/source';
// 在此傳遞 loader 資料
async function loader() {
const pageTree = source.getPageTree();
return {
pageTree: await source.serializePageTree(pageTree),
};
}Dynamic 載入器
dynamicLoader() 可為內容來源提供額外的重新驗證功能,請搭配 Dynamic 來源使用。
import { dynamicLoader } from 'fumadocs-core/source';
import { createMySource } from './my-source';
const source = dynamicLoader(createMySource(), {
baseUrl: '/docs',
});
export async function getSource() {
return source.get();
}呼叫 await source.get() 時,會回傳一個一般的內容載入器物件:
const docs = await getSource();
const page = docs.getPage(['...']);重新驗證
載入器會快取 Dynamic 來源。
如果您的來源會隨時間變動,請呼叫 invalidate() 清除快取,或呼叫 revalidate() 更新快取:
source.invalidate();
await source.revalidate();若採用多來源的設定,您可以針對特定來源進行失效 (invalidate) 或重新驗證 (revalidate) :
source.invalidate('docs');
await source.revalidate('docs');How is this guide?
最後更新於
