# Fumadocs Core (the core library of Fumadocs): 語法突顯器
URL: /zh-TW/docs/headless/utils/shiki
Source: https://raw.githubusercontent.com/fuma-nama/fumadocs/refs/heads/main/apps/docs/content/docs/headless/utils/shiki.zh-TW.mdx

使用 Shiki 或您選擇的語法突顯器，為程式碼進行語法突顯。

Fumadocs 預設使用 [Shiki](https://shiki.style) 為程式碼進行語法突顯。您也可以自行建立語法突顯器，並傳入需要語法突顯程式碼的地方；如此一來，便不會載入 Shiki。

```ts tab="Highlights" title="lib/highlighter.ts"
// npm i @pierre/highlights
import { createHighlights } from 'fumadocs-core/highlight/highlights';
import githubLight from '@pierre/highlights/themes/github-light';
import githubDark from '@pierre/highlights/themes/github-dark';

export const highlighter = createHighlights({
  themes: { light: githubLight, dark: githubDark },
});
```

```ts tab="Shiki" title="lib/highlighter.ts"
import { createShikiHighlighter } from 'fumadocs-core/highlight/shiki';
import { defaultShikiFactory } from 'fumadocs-core/highlight/shiki/full';

export const highlighter = createShikiHighlighter(() => defaultShikiFactory.getOrInit(), {
  themes: { light: 'github-light', dark: 'github-dark' },
  // Fumadocs UI 以 CSS 變數為 token 上色
  defaultColor: false,
});
```

[Highlights](https://diffs.com/highlights) 以 WebAssembly 撰寫，速度比 Shiki 快上許多倍。它內建 80 種語言 (其他語言會以純文字呈現) ，使用來自 `@pierre/highlights/themes` 的[專屬主題](https://diffs.com/docs#highlights)，並透過相容層 `shikiTransformers` 執行 Shiki transformer。

`highlighter.override()` 可使用不同的選項 (例如其他 transformer) 建立新的語法突顯器。

## 使用方式 [#usage]

`rehypeCodeFromHighlighter` 是一個 rehype 外掛。請用它取代 Fumadocs MDX 預設的 Shiki 外掛：

```ts tab="unified" title="source.config.ts"
import { defineConfig } from 'fumadocs-mdx/config';
import { rehypeCodeFromHighlighter } from 'fumadocs-core/mdx-plugins/rehype-code.core';
import { highlighter } from './lib/highlighter';

export default defineConfig({
  mdxOptions: {
    // 停用預設的 Shiki 外掛
    rehypeCodeOptions: false,
    rehypePlugins: (v) => [
      () =>
        rehypeCodeFromHighlighter(
          // 搭配 Fumadocs 的 transformer（例如標記法與圖示）建立
          ({ transformers }) => highlighter.override({ shikiTransformers: transformers }),
        ),
      ...v,
    ],
  },
});
```

```ts tab="Sätteri" title="source.config.ts"
import { defineConfig, defineDocs } from 'fumadocs-mdx/config';
import { rehypeCodeFromHighlighter } from '@fumadocs/satteri/rehype-code';
import { highlighter } from './lib/highlighter';

export const docs = defineDocs({
  docs: {
    compiler: 'satteri',
  },
});

export default defineConfig({
  satteriOptions: {
    // 停用預設的 Shiki 外掛
    rehypeCodeOptions: false,
    hastPlugins: [
      rehypeCodeFromHighlighter(
        // 搭配 Fumadocs 的 transformer（例如標記法與圖示）建立
        ({ transformers }) => highlighter.override({ shikiTransformers: transformers }),
      ),
    ],
  },
});
```

將它傳給程式碼區塊元件：

```tsx tab="Server Code Block" title="components/codeblock.tsx"
import { createServerCodeBlock } from 'fumadocs-ui/components/codeblock.rsc';
import { highlighter } from '@/lib/highlighter';

export const ServerCodeBlock = createServerCodeBlock({ highlighter });
```

```tsx tab="Dynamic Code Block" title="components/dynamic-codeblock.tsx"
'use client';
import { createDynamicCodeBlock } from 'fumadocs-ui/components/dynamic-codeblock.core';
import { highlighter } from '@/lib/highlighter';

export const DynamicCodeBlock = createDynamicCodeBlock({ highlighter });
```

各整合會在其主要進入點接收它：

| 整合                                                                                              | 選項                                                                                  |
| ----------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- |
| [本機 Markdown (Sätteri) ](/docs/next/integrations/content/satteri-local-md)                           | 在 `hastPlugins` 中使用 `@fumadocs/satteri/rehype-code` 的 `rehypeCodeFromHighlighter()` |
| [Python](/docs/next/integrations/content/python)、[Local HTML](/docs/next/integrations/content/local-html) | `createPython({ highlighter })`、`localHtml({ highlighter })`                        |
| [OpenAPI](/docs/next/integrations/openapi)、GraphQL、AsyncAPI                                          | `createOpenAPIPage({ highlighter })`                                                |
| [型別表格](/docs/ui/components/auto-type-table)                                                     | `remarkAutoTypeTable({ highlighter })`、`<AutoTypeTable highlighter />`              |
| shadcn                                                                                          | `@fumadocs/shadcn/rsc` 的 `createSnippet({ highlighter })`                           |

若 Fumadocs 會為程式碼區塊加入 transformer (例如 `rehypeCodeFromHighlighter()`，以及 Python、Local HTML 與 shadcn 的整合) ，則會改由一個函式接收這些 transformer。

## Shiki Factory [#shiki-factory]

Fumadocs 透過 Shiki factory 管理 Shiki 實例，您也可以為特定用途自行建立一個，例如使用細粒度的 bundle：

```ts
import { createShikiFactory } from 'fumadocs-core/highlight/shiki';

export const myShikiFactory = createShikiFactory({
  async init(options) {
    const { createHighlighter, createJavaScriptRegexEngine } = await import('shiki');

    return createHighlighter({
      langs: [],
      themes: [],
      langAlias: options?.langAlias,
      engine: createJavaScriptRegexEngine(),
    });
  },
});
```

接著將它傳給不同的模組／功能：

```tsx tab="Dynamic CodeBlock (UI)"
'use client';
import * as Base from 'fumadocs-ui/components/dynamic-codeblock.core';

export type DynamicCodeblockProps = Omit<Base.DynamicCodeblockProps, 'highlighter'>;

export function DynamicCodeBlock(props: DynamicCodeblockProps) {
  return <Base.DynamicCodeBlock highlighter={() => myShikiFactory.getOrInit()} {...props} />;
}
```

```ts tab="Highlighter"
import { createShikiHighlighter } from 'fumadocs-core/highlight/shiki';

export const highlighter = createShikiHighlighter(() => myShikiFactory.getOrInit(), {
  themes: { light: 'github-light', dark: 'github-dark' },
  defaultColor: false,
});
```

## 自訂語法突顯器 [#custom-highlighter]

請實作 `Highlighter` 介面：

```ts
import type { Highlighter } from 'fumadocs-core/highlight';

export const highlighter: Highlighter = {
  codeToHast(code, { lang, structure, meta }) {
    // 回傳 `pre > code > span.line`，並將 `meta` 放在 `<pre>` 上；若 `structure` 為 `inline`，則回傳 `<code>` 的內容
  },
  // 選用，用於隨需載入的語言
  async loadLanguage(...langs) {},
};
```

Fumadocs UI 會透過 `--shiki-light` 與 `--shiki-dark` 等 CSS 變數為 token 上色。您可以像傳入其他語法突顯器一樣傳入它，或使用 `rehypeCodeFromHighlighter`，在您自己的 rehype 管線中進行語法突顯：

```ts
import { rehypeCodeFromHighlighter } from 'fumadocs-core/mdx-plugins/rehype-code.core';

unified().use(rehypeCodeFromHighlighter, highlighter);
```