跳至內容
Fumadocs

MDX Remote

隨需編譯 Markdown/MDX 內容。

簡介

Fumadocs 提供 MDX Remote 套件,可協助您將 Markdown/MDX 內容來源整合至 Fumadocs。 您可以把它想成內建 Fumadocs 外掛的 next-mdx-remote。

請勿將不受信任的 MDX 傳給編譯器,因為它會在您的應用程式中以 JavaScript 執行。請改將不受信任的內容以 Markdown 格式編譯,這樣它就無法執行 JavaScript 或原始 HTML:

import { createCompiler } from '@fumadocs/mdx-remote';

const compiler = createCompiler({
  format: 'md',
  // 略過為取得圖片尺寸而讀取檔案及擷取 URL
  remarkImageOptions: false,
});

設定

npm install @fumadocs/mdx-remote

它的主要功能是 MDX 編譯器,可將 MDX 內容編譯為 JSX 節點。 由於它不使用打包工具,因此有以下限制:

  • 圖片必須在執行階段進行最佳化。
  • MDX 檔案中無法使用匯入 (import) 與匯出 (export) 。

使用方式

建立編譯器:

lib/compiler.ts
import { createCompiler } from '@fumadocs/mdx-remote';

export const compiler = createCompiler({
  // 選項
});

編譯頁面內容,其中 @/lib/source 代表您的內容來源。

compileFile() 會在 loader 中將內容編譯為 JavaScript,再由 executeMdxSync() 在用戶端執行:

src/routes/docs/$.tsx
import { createFileRoute } from '@tanstack/react-router';
import { createServerFn } from '@tanstack/react-start';
import { useMemo } from 'react';
import { executeMdxSync } from '@fumadocs/mdx-remote/client';
import { useFumadocsLoader } from 'fumadocs-core/source/client';
import { DocsLayout } from 'fumadocs-ui/layouts/docs';
import { DocsBody, DocsPage } from 'fumadocs-ui/layouts/docs/page';
import { compiler } from '@/lib/compiler';
import { getPage, source } from '@/lib/source';
import { getMDXComponents } from '@/components/mdx';

export const Route = createFileRoute('/docs/$')({
  component: Page,
  loader: ({ params }) => serverLoader({ data: params._splat?.split('/') ?? [] }),
});

const serverLoader = createServerFn({
  method: 'GET',
})
  .validator((slugs: string[]) => slugs)
  .handler(async ({ data: slugs }) => {
    const page = getPage(slugs);

    return {
      // 編譯成 JavaScript,於用戶端執行
      compiled: String(await compiler.compileFile(page.content)),
      pageTree: await source.serializePageTree(source.getPageTree()),
    };
  });

function Page() {
  const { compiled, pageTree } = useFumadocsLoader(Route.useLoaderData());
  const { default: MdxContent, toc } = useMemo(() => executeMdxSync(compiled), [compiled]);

  return (
    <DocsLayout tree={pageTree}>
      <DocsPage toc={toc}>
        <DocsBody>
          <MdxContent components={getMDXComponents()} />
        </DocsBody>
      </DocsPage>
    </DocsLayout>
  );
}

compile() 回傳的 frontmatter 屬性不會經過驗證,請使用 zod 等函式庫自行驗證。

圖片

在 Vercel 等無伺服器平台上,原本的 public 資料夾 (包含圖片等靜態資源) 會在正式環境建置完成後被移除, 因此 MDX 編譯器可能無法再存取 public 中的本機圖片。

引用圖片時,請務必使用 URL。

How is this guide?

最後更新於