# Fumadocs MDX (the built-in content source): Macro API
URL: /zh-TW/docs/mdx/macro
Source: https://raw.githubusercontent.com/fuma-nama/fumadocs/refs/heads/main/apps/docs/content/docs/mdx/macro.zh-TW.mdx

使用 fumadocs-mdx/macro 在您的應用程式中定義集合。

## 概覽 [#overview]

透過 `fumadocs-mdx/macro`，您可以直接在應用程式模組中宣告集合。

打包工具 (或執行階段載入器) 會將 `defineDocs` / `defineCollections` 編譯為內容檔案的匯入陳述式。

* 無需產生程式碼。
* 無需 `source.config.ts`。

## 使用方式 [#usage]

```ts tab="lib/source.ts"
import { defineDocs } from 'fumadocs-mdx/macro';
import { loader } from 'fumadocs-core/source';

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

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

```ts tab="lib/blog.ts"
import { defineCollections } from 'fumadocs-mdx/macro';
import { loader } from 'fumadocs-core/source';

const blog = defineCollections({
  type: 'doc',
  dir: 'content/blog',
});

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

集合選項與 [config API](/docs/mdx/collections) 大致相同。

使用巨集定義集合時，您仍可保留 `source.config.ts`，用來設定[全域選項](/docs/mdx/global)與外掛。

### 瀏覽器 [#browser]

巨集集合也能在瀏覽器中使用。只要在用戶端元件中匯入集合，再透過 `body` 算繪項目即可，不需要[用戶端載入器](/docs/mdx/entry/browser)。

```tsx
import { docs } from '@/lib/source';

export default function Page({ path }: { path: string }) {
  const page = docs.getPage(path);
  if (!page) return <div>Not Found</div>;

  const MDX = page.body;

  return (
    <div className="prose">
      <h1>{page.title}</h1>
      <MDX />
    </div>
  );
}
```

若頁面使用[路徑參數](/docs/next/page-conventions#path-params)，請從載入器傳入其參數：`docs.getPage(page.path, page.params)`。

<Callout type="warn">
瀏覽器會執行您匯入 `docs` 的來源模組的完整內容。若您的 `loader()` 包含僅限伺服器端的
來源 (例如 `openapi.staticSource()`) ，請將集合定義在另一個模組中 (例如
`lib/collections.ts`) ，再從該模組匯入。
</Callout>

#### Async 集合 [#async-collections]

啟用 [`async`](/docs/mdx/async) 後，只有 frontmatter 會預先打包，內容則會隨需擷取。

`body` 的運作方式相同，只是它會暫停 (suspend) ，直到內容可用為止。以下兩個額外的方法可控制此行為：

* `preload()` 會在算繪前先載入內容，讓 `body` 算繪時無須暫停。請在您的路由載入器中呼叫它。
* `load()` 會回傳已載入的內容，例如 `toc`。它的 promise 會被快取，因此您可以在算繪期間呼叫它。

```tsx
import { use } from 'react';
import { docs } from '@/lib/source';

// 在您的路由載入器中（React Router、TanStack Start）
export async function loader({ path }: { path: string }) {
  await docs.getPage(path)?.preload();
  return { path };
}

export default function Page({ path }: { path: string }) {
  const page = docs.getPage(path);
  if (!page) return <div>Not Found</div>;

  const { toc } = use(page.load());
  const MDX = page.body;

  return (
    <div className="prose">
      <h1>{page.title}</h1>
      <MDX />
    </div>
  );
}
```

由於內容採用延遲載入，除非您已預先載入，否則請用 `<Suspense>` 邊界包住頁面。

## 設定 [#configuration]

Macro API 預設為啟用。傳入 `macro` 可限制哪些模組能使用它，傳入 `false` 則可停用。若使用 React Router 或 TanStack Start，請將其傳給 Vite 外掛。

```js tab="Next.js" title="next.config.mjs"
import { createMDX } from 'fumadocs-mdx/next';

const withMDX = createMDX({
  macro: {
    // 相對於專案根目錄的 glob 模式
    include: ['lib/**/*.ts', 'lib/**/*.tsx'],
  },
  // 或完全停用：
  // macro: false,
});
```

```ts tab="Vite" title="vite.config.ts"
import { fumadocsMdx } from 'fumadocs-mdx/vite';

export default {
  plugins: [
    fumadocsMdx({
      macro: {
        include: ['src/**/*.ts', 'src/**/*.tsx'],
      },
    }),
  ],
};
```

```ts tab="Waku" title="waku.config.ts"
import { defineConfig } from 'waku/config';
import { fumadocsMdx } from 'fumadocs-mdx/vite';

export default defineConfig({
  vite: {
    plugins: [
      fumadocsMdx({
        macro: {
          include: ['src/**/*.ts', 'src/**/*.tsx'],
        },
      }),
    ],
  },
});
```

```js tab="Node.js"
import { register } from 'fumadocs-mdx/node';

register({
  macro: {
    include: ['lib/**/*.ts'],
  },
});
```

預設情況下，所有 JS/TS 模組都會納入處理 (`node_modules` 一律排除) 。若您希望轉換只套用於特定路徑，請縮小 `include` 的範圍。

### 限制 [#constraints]

巨集呼叫會以靜態方式編譯，請留意以下規則：

* 每個呼叫都必須指派給頂層的 `const` (變數名稱用來識別集合) ：

  ```ts
  // ✓
  const docs = defineDocs({ dir: 'content/docs' });

  // ✗ 不支援
  export function create() {
    return defineDocs({ dir: 'content/docs' });
  }
  ```

* 會影響內容打包方式的選項 (`dir`、`files`、`async`) 必須能被靜態分析 (即字串／布林值字面值) 。動態邏輯請改放在 `schema` 或 `mdxOptions` 等選項中。

* Macro API 目前尚不支援 [`dynamic`](/docs/mdx/async#dynamic-mode) 集合。如需延遲載入，建議改用 [`async`](/docs/mdx/async)。

* 不支援從 `fumadocs-mdx/macro` 重新匯出。