🎉 欢迎访问我的个人站点,这里是我日常总结和项目展示

Fumadocs 框架操作指南

本文档提供了在 Fumadocs 框架中创建和管理文档的标准操作流程

Fumadocs 框架操作指南

本文档提供了在 Fumadocs 框架中创建和管理文档的标准操作流程 (SOP),帮助你高效地管理文档内容。

新建文档集合流程

以下是在 Fumadocs 框架中新建一个文档集合的标准操作流程:

1. 创建内容目录

# 创建新的内容目录
mkdir -p content/新文档名

2. 创建初始文档

# 创建索引文件
touch content/新文档名/index.mdx

编辑 index.mdx 文件,添加基本内容:

---
title: 文档标题
description: 文档描述
---
 
# 文档标题
 
这里是文档内容...

3. 修改 source.config.ts 文件

source.config.ts 文件中添加新的文档集合定义:

// 定义新文档集合
export const 新文档变量名 = defineCollections({
  type: 'doc',
  dir: 'content/新文档名',
  schema: frontmatterSchema.extend({
    // 可以添加自定义的前置属性
    version: z.string().optional(),
    status: z.enum(['alpha', 'beta', 'stable', 'deprecated']).optional(),
    lastUpdated: z.string().date().or(z.date()).optional(),
    // 其他需要的属性...
  }),
});

4. 修改 lib/source.ts 文件

lib/source.ts 文件中添加新的加载器:

// 导入新文档集合
import { docs, blogPosts, marketingDocs, 新文档变量名 } from '@/.source';
 
// 添加新文档加载器
export const 新文档加载器名称 = loader({
  baseUrl: '/新文档路径',
  source: createMDXSource(新文档变量名),
  icon(icon) {
    if (!icon) {
      return;
    }
 
    if (icon in icons) return createElement(icons[icon as keyof typeof icons]);
  },
});

5. 创建应用路由文件

5.1 创建路由目录

# 创建路由目录
mkdir -p app/新文档路径
mkdir -p app/新文档路径/[[...slug]]

5.2 创建 layout.tsx 文件

// app/新文档路径/layout.tsx
import { DocsLayout } from 'fumadocs-ui/layouts/docs';
import type { ReactNode } from 'react';
import { baseOptions } from '@/app/layout.config';
import { 新文档加载器名称 } from '@/lib/source';
 
export default function Layout({ children }: { children: ReactNode }) {
  return (
    <DocsLayout 
      tree={新文档加载器名称.pageTree} 
      {...baseOptions}
    >
      {children}
    </DocsLayout>
  );
}

5.3 创建 [[...slug]]/page.tsx 文件

// app/新文档路径/[[...slug]]/page.tsx
import { 新文档加载器名称 } from '@/lib/source';
import {
  DocsPage,
  DocsBody,
  DocsDescription,
  DocsTitle,
} from 'fumadocs-ui/page';
import { notFound } from 'next/navigation';
import { createRelativeLink } from 'fumadocs-ui/mdx';
import { getMDXComponents } from '@/mdx-components';
 
export default async function Page(props: {
  params: Promise<{ slug?: string[] }>;
}) {
  const params = await props.params;
  const page = 新文档加载器名称.getPage(params.slug);
  if (!page) notFound();
 
  const MDXContent = page.data.body;
 
  return (
    <DocsPage 
      toc={page.data.toc} 
      full={page.data.full}
      tableOfContent={{
        style: 'clerk'
      }}
      footer={{ enabled: true }} // 启用上下一页导航
    >
      <DocsTitle>{page.data.title}</DocsTitle>
      <DocsDescription>{page.data.description}</DocsDescription>
      <DocsBody>
        <MDXContent
          components={getMDXComponents({
            // 允许使用相对文件路径链接到其他页面
            a: createRelativeLink(新文档加载器名称, page),
          })}
        />
      </DocsBody>
    </DocsPage>
  );
}
 
export async function generateStaticParams() {
  return 新文档加载器名称.generateParams();
}
 
export async function generateMetadata(props: {
  params: Promise<{ slug?: string[] }>;
}) {
  const params = await props.params;
  const page = 新文档加载器名称.getPage(params.slug);
  if (!page) notFound();
 
  return {
    title: page.data.title,
    description: page.data.description,
  };
}

6. 添加导航配置

app/layout.config.tsx 文件中添加新的导航链接:

// 添加新的导航项
{
  text: '新文档名称',
  url: '/新文档路径',
  active: 'nested-url',
},
 
// 或者添加带下拉菜单的导航项
{
  type: 'menu',
  text: '新文档名称',
  url: '/新文档路径',
  items: [
    {
      icon: <Book className="w-5 h-5" />,
      text: '开始阅读',
      description: '新文档描述',
      url: '/新文档路径',
    },
    // 其他子菜单项...
  ],
},

7. 构建并启动项目

# 清除缓存并重新构建
pnpm run clean && pnpm run build
 
# 启动开发服务器
pnpm run dev

8. 自定义侧边栏(可选)

如果需要自定义侧边栏显示,可以修改 app/docs/layout.tsx 文件:

// 显示特定菜单项
links: [linkItems[索引号]],
 
// 或者使用过滤器
links: linkItems.filter(item => item.text === '新文档名称'),

修改内容路径流程

以下是在 Fumadocs 框架中修改内容路径的标准操作流程:

1. 创建新目录并迁移内容

# 创建新目录
mkdir -p content/新目录名
 
# 复制内容到新目录
cp -r content/旧目录名/* content/新目录名/

2. 修改内容文件中的链接引用

在新目录中的 Markdown 文件内,将所有链接从旧路径更新为新路径:

<!-- 旧链接 -->
[链接文本](/旧路径/xxx)
 
<!-- 新链接 -->
[链接文本](/新路径/xxx)

3. 修改 source.config.ts 文件

这个文件定义了 Fumadocs 的内容集合和目录配置:

// 修改目录路径
export const 旧变量名 = defineCollections({
  type: 'doc',
  dir: 'content/旧目录名',  // 改为 'content/新目录名'
  ...
});
 
// 最好同时修改变量名以保持一致性
export const 新变量名 = defineCollections({
  type: 'doc',
  dir: 'content/新目录名',
  ...
});

4. 修改 lib/source.ts 文件

这个文件定义了内容加载器:

// 修改导入
import { docs, blogPosts, 旧变量名 } from '@/.source';
// 改为
import { docs, blogPosts, 新变量名 } from '@/.source';
 
// 修改加载器配置
export const 加载器名称 = loader({
  baseUrl: '/旧路径',  // 改为 '/新路径'
  source: createMDXSource(旧变量名),  // 改为 createMDXSource(新变量名)
  ...
});

5. 创建或修改应用路由文件

5.1 创建新的路由目录

# 创建路由目录
mkdir -p app/新路径
mkdir -p app/新路径/[[...slug]]

5.2 创建或修改 layout.tsx 文件

// app/新路径/layout.tsx
import { DocsLayout } from 'fumadocs-ui/layouts/docs';
import type { ReactNode } from 'react';
import { baseOptions } from '@/app/layout.config';
import { 加载器名称 } from '@/lib/source';
 
export default function Layout({ children }: { children: ReactNode }) {
  return (
    <DocsLayout 
      tree={加载器名称.pageTree} 
      {...baseOptions}
    >
      {children}
    </DocsLayout>
  );
}

5.3 创建或修改 [[...slug]]/page.tsx 文件

// app/新路径/[[...slug]]/page.tsx
import { 加载器名称 } from '@/lib/source';
import {
  DocsPage,
  DocsBody,
  DocsDescription,
  DocsTitle,
} from 'fumadocs-ui/page';
import { notFound } from 'next/navigation';
import { createRelativeLink } from 'fumadocs-ui/mdx';
import { getMDXComponents } from '@/mdx-components';
 
export default async function Page(props: {
  params: Promise<{ slug?: string[] }>;
}) {
  const params = await props.params;
  const page = 加载器名称.getPage(params.slug);
  if (!page) notFound();
 
  const MDXContent = page.data.body;
 
  return (
    <DocsPage 
      toc={page.data.toc} 
      full={page.data.full}
      tableOfContent={{
        style: 'clerk'
      }}
      footer={{ enabled: true }}
    >
      <DocsTitle>{page.data.title}</DocsTitle>
      <DocsDescription>{page.data.description}</DocsDescription>
      <DocsBody>
        <MDXContent
          components={getMDXComponents({
            a: createRelativeLink(加载器名称, page),
          })}
        />
      </DocsBody>
    </DocsPage>
  );
}
 
export async function generateStaticParams() {
  return 加载器名称.generateParams();
}
 
export async function generateMetadata(props: {
  params: Promise<{ slug?: string[] }>;
}) {
  const params = await props.params;
  const page = 加载器名称.getPage(params.slug);
  if (!page) notFound();
 
  return {
    title: page.data.title,
    description: page.data.description,
  };
}

6. 修改导航配置(如果需要)

app/layout.config.tsx 文件中更新导航链接:

{
  text: '菜单文本',
  url: '/旧路径',  // 改为 '/新路径'
  ...
},

7. 重新构建项目

# 清除缓存并重新构建
pnpm run clean && pnpm run build
 
# 启动开发服务器
pnpm run dev

8. 清理旧文件(可选)

确认新路径正常工作后,可以删除旧文件:

# 删除旧内容目录
rm -rf content/旧目录名
 
# 删除旧路由目录
rm -rf app/旧路径

自定义侧边栏菜单项

app/docs/layout.tsx 文件中,你可以通过以下方式自定义侧边栏菜单项:

/**
 * 侧边栏菜单项配置指南:
 * 1. 不显示任何菜单项: links: []
 * 2. 显示特定菜单项:
 *    - 显示博客: links: [linkItems[0]]
 *    - 显示产品小册: links: [linkItems[1]]
 *    - 显示产品: links: [linkItems[2]]
 *    - 显示照片: links: [linkItems[3]]
 *    - 显示关于: links: [linkItems[4]]
 * 3. 显示多个菜单项: links: [linkItems[0], linkItems[2]]
 * 4. 使用过滤器: 
 *    - 只显示特定文本的菜单项: links: linkItems.filter(item => item.text === '博客' || item.text === '关于')
 *    - 只显示类型为'menu'的菜单项: links: linkItems.filter(item => item.type === 'menu'),
 */

按照这些标准操作流程,你可以轻松地在 Fumadocs 框架中创建新的文档集合、修改内容路径,并确保它们正确显示在网站上。