跳至內容
Fumadocs

來源

為載入器 API 設定來源

概覽

內容載入器透過 source 介面,可接受各種不同的內容來源。

多個來源

請改為傳入由多個來源物件組成的物件 (Record)

import { loader } from 'fumadocs-core/source';
import { blog, docs } from 'collections/server';
import { lucideIconsPlugin } from 'fumadocs-core/source/lucide-icons';

export const source = loader(
  {
    docs: docs.toFumadocsSource(),
    openapi: blog.toFumadocsSource(),
  },
  {
    baseUrl: '/docs',
  },
);

若要存取各個來源專屬的屬性:

const page = source.getPage(['...']);

if (page.type === 'docs') {
  console.log(page.data);
} else {
  console.log(page.data);
}

靜態來源

若要接入您自己的內容來源,請建立 StaticSource 物件。

由於載入器 API 不依賴檔案系統,檔案路徑僅能使用虛擬路徑,例如 file.mdx 和 content/file.mdx;./file.mdx 和 D://content/file.mdx 則不允許使用。

import type {  } from 'fumadocs-core/source';

export function (): <{
  : { : string; : string[] }; // 您的自訂型別
  : { : string; ?: string }; // 您的自訂型別
}> {
  return {
    : [
      {
        : 'page',
        : 'folder/index.mdx',
        : {
          : 'Hello World',
          // ...
        },
      },
      {
        : 'meta',
        : 'meta.json',
        : {
          : 'Docs',
          : ['folder'],
          // ...
        },
      },
    ],
  };
}

啟用 i18n 時,除非檔案有指定 locale,否則檔案的語言會從其路徑解析而來。

Dynamic 來源

若內容來源支援重新驗證 (revalidation) ,請改為回傳 DynamicSource:

import type { DynamicSource } from 'fumadocs-core/source';

export function createMySource(): DynamicSource<{
  metaData: { title: string; pages: string[] };
  pageData: { title: string; description?: string };
}> {
  return {
    async files() {
      return [
        {
          type: 'page',
          path: 'folder/index.mdx',
          data: {
            title: 'Hello World',
          },
        },
        {
          type: 'meta',
          path: 'meta.json',
          data: {
            title: 'Docs',
            pages: ['folder'],
          },
        },
      ];
    },
    configure(loader) {
      // 您可以在來源中重新驗證載入器,例如:
      onMyEvent(() => {
        void loader.revalidate();
      });
    },
  };
}

Dynamic 來源只能交由 dynamicLoader() 使用。

路徑參數

若要在您的來源中支援路徑參數,請將 [framework]/deploy.mdx 這類檔案作為單一虛擬檔案傳入。載入器會為每個值各產生一個頁面,資料來自 dataAt();若未提供 dataAt(),則使用 data。Meta 檔案的運作方式也相同:

import type {  } from 'fumadocs-core/source';

const : ['files'] = [
  {
    : 'page',
    : '[framework]/deploy.mdx',
    : { : 'Deploy' },
    : () => ({ : `Deploy on ${.framework}` }),
  },
  {
    : 'meta',
    : '[framework]/meta.json',
    : { : [{ : 'waku' }, { : 'astro' }] },
    : () => ({ : .framework }),
  },
];

列出參數

為了在載入器之前先解析每個值的資料 (例如程式碼中的 frontmatter) ,getStaticParams() 會依照相同規則列出參數。它會依據不含副檔名的路徑,從您的儲存空間讀取 meta 檔案中的 staticParams:

const  = ('[framework]/deploy.mdx', {
  : .,
  : () => .()?.,
});

若沒有任何地方列出這些值,它會回傳 undefined,此時該檔案會以其字面路徑產生單一頁面。

自訂 Props

為了支援自訂 props,dataAt() 會將它們作為第二個引數接收,同時傳入經過載入器外掛處理後的頁面資料。請回傳依據參數與自訂 props 算繪後的資料:

const : ['files'] = [
  {
    : 'page',
    : '[framework]/deploy.mdx',
    : ({}),
    : (, ) =>
       ? { ...., ...({ ..., .... }) } : (),
  },
];

未使用 dataAt() 的頁面會忽略自訂 props。

執行階段輸出

若您的來源會編譯 MDX,請將每個檔案只編譯一次,並將頁面 props 傳入其內容。若要以相同的 props 產生目錄、搜尋紀錄與 Markdown:

  • 在要編譯的檔案資料中設定 unstable_runtimeOutputs: true。若使用 Sätteri,請在編譯選項的 data 中設定。
  • 將 rehypeHeading 加為最後一個 rehype 外掛,以便根據算繪後的文字產生標題 ID。
import { VFile } from 'vfile';

const file = new VFile({
  path: '[framework]/deploy.mdx',
  value: source,
  data: { unstable_runtimeOutputs: true },
});

此時外掛匯出的會是函式而非值,例如 Rehype 目錄 的 toc,以及 Remark LLMs 的 _markdown 元件。請傳入各頁面的 props 來呼叫它們:

const { : , , :  } = ;

function (: object) {
  return {
    : 'Deploy',
    : (: MDXProps) => < {...} {...} />,
    : (),
    : () => (< {...} />),
    : ..,
  };
}

const : ['files'] = [
  {
    : 'page',
    : '[framework]/deploy.mdx',
    : ({}),
    : () => (),
  },
];

若要用於搜尋,請從 file.data.structuredData 讀取 Remark Structure 的紀錄,而非從匯出內容讀取。這些紀錄涵蓋每個 <show> 分支,而表達式也會保留其原始文字。

unstable_ 前綴表示此 API 日後可能變更。若未啟用此旗標,在執行 Rehype 目錄、Remark Structure 或 Remark LLMs 時,含有 <show> 的文件將無法編譯。

How is this guide?

最後更新於