跳至內容
Fumadocs

本機 Markdown(Sätteri)

適用於本機 Markdown 內容的內容來源,以 Sätteri 編譯。

簡介

@fumadocs/satteri/local-md 是適用於本機 Markdown/MDX 檔案的內容來源,改用 Sätteri 編譯,而非 unified/remark 管線。

它與 @fumadocs/local-md 的 API 相同,同樣無需打包,因此可直接在執行階段運作,不需要型別產生或打包步驟。

若您想使用 Sätteri 編譯器、它的外掛模型,以及 Fumadocs Sätteri 預設組合,請選用此內容來源。

差異

  • 編譯結果一律為 JavaScript,因此不提供虛擬 JavaScript 引擎選項,算繪時會使用原生引擎。
  • 外掛為 Sätteri 外掛,需透過 satteriOptions 設定,而非 remark/rehype 外掛。

請勿將不受信任的 Markdown/MDX 檔案放在 dir 中,因為這些檔案可能會以 JavaScript 形式執行,或參照伺服器端的檔案。

安裝設定

npm install @fumadocs/satteri shiki

之所以需要安裝 shiki,是因為打包工具必須將它外部化 (externalize) 。

建立 localMd 實例,並將它連接到 Fumadocs:

lib/source.ts
import { dynamicLoader } from 'fumadocs-core/source';
import { localMd } from '@fumadocs/satteri/local-md';

const docs = localMd({
  dir: 'content/docs',
});

const docsLoader = dynamicLoader(docs.dynamicSource(), {
  baseUrl: '/docs',
});

export async function getSource() {
  return docsLoader.get();
}

Schema

傳入 frontmatterSchema 與 metaSchema,即可自訂驗證用的 schema:

lib/source.ts
import { localMd } from '@fumadocs/satteri/local-md';
import { pageSchema, metaSchema } from 'fumadocs-core/source/schema';

const docs = localMd({
  dir: 'content/docs',
  frontmatterSchema: pageSchema.extend({
    // ...
  }),
  metaSchema: metaSchema.extend({
    // ...
  }),
});

編譯器選項

satteriOptions 會經由 Fumadocs Sätteri 預設集傳入,因此外掛及其選項的設定方式與 Fumadocs MDX 相同:

lib/source.ts
const docs = localMd({
  dir: 'content/docs',
  satteriOptions: {
    rehypeCodeOptions: {
      themes: { light: 'github-light', dark: 'github-dark' },
    },
    mdastPlugins: [myPlugin()],
  },
});

傳入函式即可延遲建立選項。

使用方式

getSource() 會回傳一個內容載入器。算繪頁面的方式與 @fumadocs/local-md 相同,只是改從 @fumadocs/satteri/local-md 匯入。

每個頁面都有 load(),可編譯該頁面並回傳算繪器:

const page = source.getPage(slugs);
const { body, toc } = await (await page.data.load()).render();

算繪器也提供 structuredData 與 exports,可用來取得文件或其外掛所匯出的值。

引入

<include> 與 ::include 指令皆已預設啟用:

content/docs/page.mdx
<include>../shared/note.md</include>

熱重載

來源會在執行階段讀取檔案,因此預設不會監看這些檔案。

在開發期間,請在執行應用程式的同時,執行 @fumadocs/local-md 的開發伺服器:

package.json
{
  "scripts": {
    "dev": "local-md dev -- next dev"
  }
}

將來源連接至該伺服器:

lib/source.ts
import { watchWithDevServer } from '@fumadocs/satteri/local-md/dev/ws';

if (process.env.NODE_ENV === 'development') {
  void watchWithDevServer(docs);
}

這會讓伺服器上的來源失效,但 Next.js 仍會在瀏覽器中保留已算繪的頁面。請在根版面配置中算繪 <DevClient />,讓頁面也一併重新整理:

app/layout.tsx
import { DevClient } from '@fumadocs/satteri/local-md/dev/react-client';

export function RootLayout({ children }) {
  return (
    <RootProvider>
      <DevClient />
      {children}
    </RootProvider>
  );
}

引入的檔案也會受到監看。若要自行串接監看器,請監看 docs.dir 以及傳入 docs.onDependency() 的檔案,並在檔案變更時呼叫 docs.invalidateFile(path)。

停用重新驗證

若您只需要一次性的快照,請使用 staticSource(),如此一來,一般的 loader() 即可正常運作:

lib/source.ts
import { loader } from 'fumadocs-core/source';

export const source = loader(await docs.staticSource(), {
  baseUrl: '/docs',
});

How is this guide?

最後更新於