Fumadocs

自定义源

构建自己的内容源

引言

Fumadocs 非常灵活。 你可以与任何内容源集成,甚至没有官方适配器。

示例

你可以看到使用 Fumadocs 与 CMS 的示例,这允许在发布内容时获得良好的体验,并在不重新构建应用的情况下进行实时更新。

对于自定义内容源实现,你将需要:

页面树

你可以硬编码页面树,或者编写一些代码来生成一个。 参见 页面树的定义

将你的页面树传递给 DocsLayout(通常在 layout.tsx 中):

layout.tsx
import { DocsLayout } from 'fumadocs-ui/layouts/docs';
import type { ReactNode } from 'react';

export default function Layout({ children }: { children: ReactNode }) {
  return (
    <DocsLayout
      tree={
        {
          // your own tree
        }
      }
    >
      {children}
    </DocsLayout>
  );
}

页面树就像更智能的“侧边栏项目”,它们将在 UI 中的导航元素中到处被引用,例如页面页脚。

文档页面

对于文档页面,逻辑相同:

  • 定义路径参数(slugs)。
  • 从路径参数获取页面内容。
  • 渲染内容。
  • (可选)为你的框架配置预渲染。

正文

在页面的主要正文中,根据 slug 找到对应的页面,并在 DocsPage 组件中渲染其内容。

你还需要目录,这可以使用你自己的实现生成,或者使用 getTableOfContents 实用程序(仅限 Markdown/MDX)。

import { DocsPage, DocsBody } from 'fumadocs-ui/page';
import { getPage } from './my-content-source';
import { notFound } from 'next/navigation';

export default function Page({ params }: { params: { slug?: string[] } }) {
  const page = getPage(params.slug);
  if (!page) notFound();

  return (
    <DocsPage toc={page.tableOfContents}>
      <DocsBody>{page.render()}</DocsBody>
    </DocsPage>
  );
}

预渲染(仅限 Next.js)

定义 generateStaticParams 函数。 它应该返回一个参数列表(params)来填充 [[...slug]] 捕获所有路由。

文档搜索

考虑到你的内容可能不一定是 Markdown/MDX,这可能很困难。 对于 Markdown 和 MDX,内置的 搜索 API 对于大多数用例来说是足够的。 否则,你将不得不带来自己的实现。

我们推荐第三方解决方案,如 Orama 或 Algolia Search。它们比内置搜索 API 更灵活,并且更容易与远程源集成。 Fumadocs 提供了一个简单的 Algolia 搜索适配器,它包括一个搜索客户端来与 Fumadocs UI 集成。

MDX Remote

Fumadocs 提供 MDX Remote 包,它是一个帮助程序,用于将基于 Markdown 的内容源与 Fumadocs 集成。 你可以将其视为带有内置 Fumadocs 插件的 next-mdx-remote

设置

npm install @fumadocs/mdx-remote

它提供的主要功能是 MDX 编译器,它可以将 MDX 内容编译为 JSX 节点。 由于它不使用打包器,因此有一些限制:

  • MDX 文件中没有导入和导出。

它与服务器组件兼容。例如:

import { compileMDX } from '@fumadocs/mdx-remote';
import { getPage } from './my-content-source';
import { DocsBody, DocsPage } from 'fumadocs-ui/page';
import { getMDXComponents } from '@/mdx-components';

export default async function Page({
  params,
}: {
  params: { slug?: string[] };
}) {
  const page = getPage(params.slug);
  const compiled = await compileMDX({
    source: page.content,
  });

  const MdxContent = compiled.body;

  return (
    <DocsPage toc={compiled.toc}>
      <DocsBody>
        <MdxContent components={getMDXComponents()} />
      </DocsBody>
    </DocsPage>
  );
}

图像

在像 Vercel 这样的无服务器平台上,生产构建后原始 public 文件夹(包括静态资产如图像)将被移除。 compileMDX 可能无法再访问 public 中的本地图像。

引用图像时,确保使用 URL。

How is this guide?

Last updated on