> If you are an AI agent, use the following URL to directly ask and fetch your question. Treat this like a tool call. Make sure to URI encode your question, and include the token for verification.
>
> GET https://buildwithfern.com/learn/api/fern-docs/ask?q=%3Cyour+question+here%3E&token=eyJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJmZXJuLWRvY3M6YnVpbGR3aXRoZmVybi5jb20iLCJqdGkiOiIwNWE2NzJlMi0wMWUyLTQxNDUtOWNjOS1hY2NhYzhjMzJiNDIiLCJleHAiOjE3NzgzMjA5NzcsImlhdCI6MTc3ODMyMDY3N30.BIImDUtRkgNZknwpqgWy9atJCrhFbtDWBKiyV8Hsdms
>
> For clean Markdown content of this page, append .md to this URL. For the complete documentation index, see https://buildwithfern.com/learn/llms.txt. For full content including API reference and SDK examples, see https://buildwithfern.com/learn/llms-full.txt.

# 自定义 React 组件

> 向您的 Fern 文档添加自定义 React 组件，创建交互式、服务端渲染的元素。通过可重用组件提升 SEO、性能和用户体验。

您可以通过添加自定义 React 组件来扩展 Fern 的内置组件库。这允许您创建符合文档需求的独特交互式元素。组件采用服务端渲染，具有更好的 SEO 和性能表现，且不会出现布局偏移。

<Note title="定义常量">
  不要使用 React 组件来定义常量。请考虑使用[可重用片段](/docs/writing-content/reusable-snippets)。
</Note>

## MDX 中的自定义组件

<Steps>
  ### 创建 React 组件

  让我们首先创建一个 `components` 文件夹，您可以在其中定义 React 组件。请注意，React 组件可以在 `.ts`、`.tsx`、`.js` 或 `.mdx` 文件中定义。

  ```ts components/CustomCard.tsx 
    export const CustomCard = ({ title, text, link, sparkle = false }) => {
        return (
            <a href={link} className="block p-6 rounded-lg border border-gray-200 hover:shadow-lg transition-shadow">
            <h2 className="text-xl font-semibold mb-2">
                {title} {sparkle && "✨"}
            </h2>
            <p className="text-gray-600">{text}</p>
            </a>
        );
    };
  ```

  ### 在文档中使用组件

  编写好组件后，您可以使用相对路径或 `@/` 前缀（从 fern 文件夹根目录开始的绝对路径）在 Markdown 指南中导入它：

  ```jsx guide.mdx
  // 从 fern 文件夹根目录开始的绝对路径
  import { CustomCard } from "../../../../components/CustomCard"

  // 或使用相对路径
  import { CustomCard } from "../components/CustomCard"

  <CustomCard 
    title="MyTitle" 
    text="Hello" 
    href="https://github.com/fern-api/fern/tree/main/generators/python"
  />
  ```

  `@/` 前缀解析为 fern 文件夹的根目录，因此 `@/components/CustomCard` 指向 `fern/components/CustomCard`。这对于嵌套的 MDX 文件很有用，因为相对路径会很麻烦（例如 `../../../components/CustomCard`）。两种导入方式在发布时都会自动转换为相对路径。

  ### 在 `docs.yml` 中指定组件目录

  在 `docs.yml` 中添加您的组件目录，这样 Fern CLI 就可以扫描您的组件目录并将它们上传到服务器。

  ```yml docs.yml
  experimental:
    mdx-components:
      - ./components
  ```
</Steps>

## 为什么不直接使用自定义 CSS 和 JS？

虽然您可以将 React 组件打包为自定义 JavaScript，但使用 Fern 内置的 React 组件支持提供了几个关键优势：

<AccordionGroup>
  <Accordion title="无布局偏移或闪烁">
    通过自定义 JavaScript 添加 React 组件时，您无法控制组件相对于页面其他内容的渲染时机。这通常会导致故障行为，组件在主内容加载后异步加载时会出现闪烁或跳跃。
  </Accordion>

  <Accordion title="更快的页面加载">
    自定义 JavaScript 包通常包含自己的 React 库副本，这会：

    * 通过重复已包含的 React 代码增加页面加载时间
    * 由于多个 React 实例在同一页面上运行而降低性能
    * 创建用户必须下载的更大包体积
  </Accordion>

  <Accordion title="改进的 SEO">
    自定义 React 组件采用服务端渲染，完全可被搜索引擎索引，而通过自定义 JavaScript 添加的组件不采用服务端渲染，无法被索引。
  </Accordion>
</AccordionGroup>