Revert "cf: test remove docs pages and docs+blog content"

This reverts commit c3392320b3.
This commit is contained in:
javayhu 2025-06-09 00:21:34 +08:00
parent f3b6603db7
commit 593333c3dd
16 changed files with 3254 additions and 0 deletions

View File

@ -0,0 +1,78 @@
---
title: Comparisons
description: How is Fumadocs different from other existing frameworks?
image: /images/blog/post-2.png
date: 2025-03-22T12:00:00.000Z
published: true
categories: [news, company]
author: fox
---
## Nextra
Fumadocs is highly inspired by Nextra. For example, the Routing Conventions. That is why
`meta.json` also exists in Fumadocs.
Nextra is more opinionated than Fumadocs. Fumadocs is accelerated by App Router. As a result, It provides many server-side functions, and you have to
configure things manually compared to simply editing a configuration file.
Fumadocs works great if you want more control over everything, such as
adding it to an existing codebase or implementing advanced routing.
### Feature Table
| Feature | Fumadocs | Nextra |
| ------------------- | ------------ | ------------------------- |
| Static Generation | Yes | Yes |
| Cached | Yes | Yes |
| Light/Dark Mode | Yes | Yes |
| Syntax Highlighting | Yes | Yes |
| Table of Contents | Yes | Yes |
| Full-text Search | Yes | Yes |
| i18n | Yes | Yes |
| Last Git Edit Time | Yes | Yes |
| Page Icons | Yes | Yes, via `_meta.js` files |
| RSC | Yes | Yes |
| Remote Source | Yes | Yes |
| SEO | Via Metadata | Yes |
| Built-in Components | Yes | Yes |
| RTL Layout | Yes | Yes |
### Additional Features
Features supported via 3rd party libraries like [TypeDoc](https://typedoc.org) will not be listed here.
| Feature | Fumadocs | Nextra |
| -------------------------- | -------- | ------ |
| OpenAPI Integration | Yes | No |
| TypeScript Docs Generation | Yes | No |
| TypeScript Twoslash | Yes | Yes |
## Mintlify
Mintlify is a documentation service, as compared to Fumadocs, it offers a free tier but isn't completely free and open source.
Fumadocs is not as powerful as Mintlify, for example, the OpenAPI integration of Mintlify.
As the creator of Fumadocs, I wouldn't recommend switching to Fumadocs from Mintlify if you're satisfied with the current way you build docs.
However, I believe Fumadocs is a suitable tool for all Next.js developers who want to have elegant docs.
## Docusaurus
Docusaurus is a powerful framework based on React.js. It offers many cool
features with plugins and custom themes.
### Better DX
Since Fumadocs is built on the top of Next.js, you'll have to start the Next.js dev
server every time to review changes, and initial boilerplate code is relatively more
compared to Docusaurus.
For a simple docs, Docusaurus might be a better choice if you don't need any Next.js specific functionality.
However, when you want to use Next.js, or seek extra customizability like tuning default UI components, Fumadocs could be a better choice.
### Plugins
You can easily achieve many things with plugins, their ecosystem is indeed larger and maintained by many contributors.
In comparison, the flexibility of Fumadocs allows you to implement them on your own, it may take longer to tune it to your satisfaction.

View File

@ -0,0 +1,72 @@
---
title: 对比
description: Fumadocs 与其他现有框架有何不同?
image: /images/blog/post-2.png
date: 2025-03-22T12:00:00.000Z
published: true
categories: [news, company]
author: fox
---
## Nextra
Fumadocs 深受 Nextra 启发。例如,路由约定。这就是为什么 Fumadocs 中也存在 `meta.json`。
Nextra 比 Fumadocs 更加固执己见。Fumadocs 由 App Router 加速。因此,它提供了许多服务器端功能,与简单编辑配置文件相比,您必须手动配置一些内容。
如果您想要对一切都有更多的控制比如将其添加到现有代码库或实现高级路由Fumadocs 会表现得很出色。
### 功能表
| 功能 | Fumadocs | Nextra |
| ------------------- | ------------ | ------------------------- |
| 静态生成 | 是 | 是 |
| 缓存 | 是 | 是 |
| 明/暗模式 | 是 | 是 |
| 语法高亮 | 是 | 是 |
| 目录 | 是 | 是 |
| 全文搜索 | 是 | 是 |
| 国际化 | 是 | 是 |
| 最后 Git 编辑时间 | 是 | 是 |
| 页面图标 | 是 | 是,通过 `_meta.js` 文件 |
| RSC | 是 | 是 |
| 远程源 | 是 | 是 |
| SEO | 通过元数据 | 是 |
| 内置组件 | 是 | 是 |
| RTL 布局 | 是 | 是 |
### 附加功能
通过第三方库支持的功能(如 [TypeDoc](https://typedoc.org))不会在此列出。
| 功能 | Fumadocs | Nextra |
| -------------------------- | -------- | ------ |
| OpenAPI 集成 | 是 | 否 |
| TypeScript 文档生成 | 是 | 否 |
| TypeScript Twoslash | 是 | 是 |
## Mintlify
Mintlify 是一项文档服务,与 Fumadocs 相比,它提供免费套餐,但并非完全免费和开源。
Fumadocs 不如 Mintlify 强大,例如 Mintlify 的 OpenAPI 集成。
作为 Fumadocs 的创建者,如果您对当前构建文档的方式感到满意,我不建议从 Mintlify 切换到 Fumadocs。
然而,我相信 Fumadocs 是所有想要拥有优雅文档的 Next.js 开发者的合适工具。
## Docusaurus
Docusaurus 是一个基于 React.js 的强大框架。它通过插件和自定义主题提供了许多酷炫的功能。
### 更好的开发者体验
由于 Fumadocs 构建在 Next.js 之上,您每次都必须启动 Next.js 开发服务器来查看更改,并且相对于 Docusaurus初始样板代码较多。
对于简单的文档,如果您不需要任何特定于 Next.js 的功能Docusaurus 可能是更好的选择。
然而,当您想要使用 Next.js或寻求更多的可定制性如调整默认 UI 组件时Fumadocs 可能是更好的选择。
### 插件
您可以通过插件轻松实现许多功能,他们的生态系统确实更大,并由许多贡献者维护。
相比之下Fumadocs 的灵活性允许您自己实现它们,可能需要更长的时间来调整它以达到您的满意度。

278
content/blog/fumadocs.mdx Normal file
View File

@ -0,0 +1,278 @@
---
title: Quick Start
description: Getting Started with Fumadocs
image: /images/blog/post-8.png
date: 2025-03-28T12:00:00.000Z
published: true
categories: [company, news]
author: mksaas
---
## Introduction
Fumadocs <span className='text-fd-muted-foreground text-sm'>(Foo-ma docs)</span> is a **documentation framework** based on Next.js, designed to be fast, flexible,
and composes seamlessly into Next.js App Router.
Fumadocs has different parts:
<Cards>
<Card icon={<CpuIcon className="text-purple-300" />} title='Fumadocs Core'>
Handles most of the logic, including document search, content source adapters, and Markdown extensions.
</Card>
<Card icon={<PanelsTopLeft className="text-blue-300" />} title='Fumadocs UI'>
The default theme of Fumadocs offers a beautiful look for documentation sites and interactive components.
</Card>
<Card icon={<Database />} title='Content Source'>
The source of your content, can be a CMS or local data layers like [Content Collections](https://www.content-collections.dev) and [Fumadocs MDX](/docs/mdx), the official content source.
</Card>
<Card icon={<Terminal />} title='Fumadocs CLI'>
A command line tool to install UI components and automate things, useful for customizing layouts.
</Card>
</Cards>
<Callout title="Want to learn more?">
Read our in-depth [What is Fumadocs](/docs/what-is-fumadocs) introduction.
</Callout>
### Terminology
**Markdown/MDX:** Markdown is a markup language for creating formatted text. Fumadocs supports Markdown and MDX (superset of Markdown) out-of-the-box.
Although not required, some basic knowledge of Next.js App Router would be useful for further customisations.
## Automatic Installation
A minimum version of Node.js 18 required, note that Node.js 23.1 might have problems with Next.js production build.
<Tabs groupId='package-manager' persist items={['npm', 'pnpm', 'yarn', 'bun']}>
```bash tab="npm"
npm create fumadocs-app
```
```bash tab="pnpm"
pnpm create fumadocs-app
```
```bash tab="yarn"
yarn create fumadocs-app
```
```bash tab="bun"
bun create fumadocs-app
```
</Tabs>
It will ask you the framework and content source to use, a new fumadocs app should be initialized. Now you can start hacking!
<Callout title='From Existing Codebase?'>
You can follow the [Manual Installation](/docs/manual-installation) guide to get started.
</Callout>
### Enjoy!
Create your first MDX file in the docs folder.
```mdx title="content/docs/index.mdx"
---
title: Hello World
---
## Yo what's up
```
Run the app in development mode and see http://localhost:3000/docs.
```package-install
npm run dev
```
## Explore
In the project, you can see:
- `lib/source.ts`: Code for content source adapter, [`loader()`](/docs/headless/source-api) provides an interface to interact with your content source, and assigns URL to your pages.
- `app/layout.config.tsx`: Shared options for layouts, optional but preferred to keep.
| Route | Description |
| ------------------------- | ------------------------------------------------------ |
| `app/(home)` | The route group for your landing page and other pages. |
| `app/docs` | The documentation layout and pages. |
| `app/api/search/route.ts` | The Route Handler for search. |
### Writing Content
For authoring docs, make sure to read:
<Cards>
<Card href="/docs/markdown" title="Markdown">
Fumadocs has some additional features for authoring content too.
</Card>
<Card href="/docs/navigation" title="Navigation">
Learn how to customise navigation links/sidebar items.
</Card>
</Cards>
### Content Source
Content source handles all your content, like compiling Markdown files and validating frontmatter.
<Tabs items={['Fumadocs MDX', 'Custom Source']}>
<Tab value='Fumadocs MDX'>
Read the [Introduction](/docs/mdx) to learn how it handles your content.
A `source.config.ts` config file has been included, you can customise different options like frontmatter schema.
</Tab>
<Tab value='Custom Source'>
Fumadocs is not Markdown-exclusive. For other sources like Sanity, you can build a [custom content source](/docs/headless/custom-source).
</Tab>
</Tabs>
### Customise UI
See [Customisation Guide](/docs/customisation).
## FAQ
Some common questions you may encounter.
<Accordions>
<Accordion id='fix-monorepo-styling' title="How to fix stylings not being applied in Monorepo?">
Sometimes, `fumadocs-ui` is not installed in the workspace of your Tailwind CSS configuration file. (e.g. a monorepo setup).
You have to ensure the `fumadocs-ui` package is scanned by Tailwind CSS, and give a correct relative path to `@source`.
For example, add `../../` to point to the `node_modules` folder in root workspace.
```css
@import 'tailwindcss';
@import 'fumadocs-ui/css/neutral.css';
@import 'fumadocs-ui/css/preset.css';
/* [!code --] */
@source '../node_modules/fumadocs-ui/dist/**/*.js';
/* [!code ++] */
@source '../../../node_modules/fumadocs-ui/dist/**/*.js';
```
</Accordion>
<Accordion id='change-base-url' title="How to change the base route of /docs?">
You can change the base route of docs (e.g. from `/docs/page` to `/info/page`).
Since Fumadocs uses Next.js App Router, you can simply rename the route:
<Files>
<Folder name="app/docs" defaultOpen className="opacity-50" disabled>
<File name="layout.tsx" />
</Folder>
<Folder name="app/info" defaultOpen>
<File name="layout.tsx" />
</Folder>
</Files>
And tell Fumadocs to use the new route in `source.ts`:
```ts title="lib/source.ts"
import { loader } from 'fumadocs-core/source';
export const source = loader({
baseUrl: '/info',
// other options
});
```
</Accordion>
<Accordion id='dynamic-route' title="It uses Dynamic Route, will it be poor in performance?">
Next.js turns dynamic route into static routes when `generateStaticParams` is configured.
Hence, it is as fast as static pages.
You can enable Static Exports on Next.js to get a static build output. (Notice that Route Handler doesn't work with static export, you have to configure static search)
</Accordion>
<Accordion id='custom-layout-docs-page' title='How to create a page in /docs without docs layout?'>
Same as managing layouts in Next.js App Router, remove the original MDX file from content directory (`/content/docs`).
This ensures duplicated pages will not cause errors.
Now, You can add the page to another route group, which isn't a descendant of docs layout.
For example, under your `app` folder:
<Files>
<File name="(home)/docs/page.tsx" />
<Folder name="docs">
<File name="layout.tsx" />
<File name="[[...slug]]/page.tsx" />
</Folder>
</Files>
will replace the `/docs` page with your `page.tsx`.
</Accordion>
<Accordion id='multi-versions' title="How to implement docs with multi-version?">
Use a separate deployment for each version.
On Vercel, this can be done by creating another branch for a specific version on your GitHub repository.
To link to the sites of other versions, use the Links API or a custom navigation component.
</Accordion>
<Accordion id='multi-docs' title="How to implement multi-docs?">
We recommend to use [Sidebar Tabs](/docs/navigation/sidebar#sidebar-tabs).
</Accordion>
</Accordions>
## Learn More
New to here? Don't worry, we are welcome for your questions.
If you find anything confusing, please give your feedback on [Github Discussion](https://github.com/fuma-nama/fumadocs/discussions)!
<Cards>
<Card
href="/docs/static-export"
title="Configure Static Export"
description="Learn how to enable static export on your docs"
/>
<Card
href="/docs/search"
title="Customise Search"
description="Learn how to customise document search"
/>
<Card
href="/docs/theme"
title="Theming"
description="Add themes to Fumadocs UI"
/>
<Card
href="/docs/components"
title="Components"
description="See all available components to enhance your docs"
/>
</Cards>

View File

@ -0,0 +1,253 @@
---
title: 快速入门
description: Fumadocs 入门指南
image: /images/blog/post-8.png
date: 2025-03-28T12:00:00.000Z
published: true
categories: [company, news]
author: mksaas
---
## 简介
Fumadocs <span className='text-fd-muted-foreground text-sm'>(Foo-ma docs)</span> 是一个基于 Next.js 的**文档框架**,设计为快速、灵活,
并无缝集成到 Next.js App Router 中。
Fumadocs 由不同部分组成:
<Cards>
<Card icon={<CpuIcon className="text-purple-300" />} title='Fumadocs Core'>
处理大部分逻辑,包括文档搜索、内容源适配器和 Markdown 扩展。
</Card>
<Card icon={<PanelsTopLeft className="text-blue-300" />} title='Fumadocs UI'>
Fumadocs 的默认主题为文档站点提供了美观的外观和交互式组件。
</Card>
<Card icon={<Database />} title='Content Source'>
您内容的来源,可以是 CMS 或本地数据层,如 [Content Collections](https://www.content-collections.dev) 和 [Fumadocs MDX](/docs/mdx),即官方内容源。
</Card>
<Card icon={<Terminal />} title='Fumadocs CLI'>
一个命令行工具,用于安装 UI 组件和自动化操作,对于自定义布局非常有用。
</Card>
</Cards>
<Callout title="想了解更多?">
阅读我们深入的 [什么是 Fumadocs](/docs/what-is-fumadocs) 介绍。
</Callout>
### 术语
**Markdown/MDX:** Markdown 是一种用于创建格式化文本的标记语言。Fumadocs 默认支持 Markdown 和 MDXMarkdown 的超集)。
虽然不是必需的,但对 Next.js App Router 的基本了解对于进一步的自定义会很有帮助。
## 自动安装
需要 Node.js 18 或更高版本,请注意 Node.js 23.1 可能在 Next.js 生产构建中存在问题。
<Tabs groupId='package-manager' persist items={['npm', 'pnpm', 'yarn', 'bun']}>
```bash tab="npm"
npm create fumadocs-app
```
```bash tab="pnpm"
pnpm create fumadocs-app
```
```bash tab="yarn"
yarn create fumadocs-app
```
```bash tab="bun"
bun create fumadocs-app
```
</Tabs>
它会询问您要使用的框架和内容源,随后将初始化一个新的 fumadocs 应用程序。现在您可以开始动手了!
<Callout title='从现有代码库开始?'>
您可以按照 [手动安装](/docs/manual-installation) 指南开始。
</Callout>
### 尽情使用!
在 docs 文件夹中创建您的第一个 MDX 文件。
```mdx title="content/docs/index.mdx"
---
title: Hello World
---
## Yo what's up
```
在开发模式下运行应用程序并查看 http://localhost:3000/docs。
```package-install
npm run dev
```
## 探索
在项目中,您可以看到:
- `lib/source.ts`:内容源适配器的代码,[`loader()`](/docs/headless/source-api) 提供了与内容源交互的接口,并为您的页面分配 URL。
- `app/layout.config.tsx`:布局的共享选项,可选但建议保留。
| 路由 | 描述 |
| ------------------------- | -------------------------------------- |
| `app/(home)` | 您的登陆页面和其他页面的路由组。 |
| `app/docs` | 文档布局和页面。 |
| `app/api/search/route.ts` | 搜索的路由处理器。 |
### 编写内容
对于编写文档,请务必阅读:
<Cards>
<Card href="/docs/markdown" title="Markdown">
Fumadocs 还有一些额外的内容创作功能。
</Card>
<Card href="/docs/navigation" title="Navigation">
了解如何自定义导航链接/侧边栏项目。
</Card>
</Cards>
### 内容源
内容源处理您的所有内容,例如编译 Markdown 文件和验证前言。
<Tabs items={['Fumadocs MDX', 'Custom Source']}>
<Tab value='Fumadocs MDX'>
阅读 [介绍](/docs/mdx) 了解它如何处理您的内容。
项目中已包含 `source.config.ts` 配置文件,您可以自定义不同的选项,如前言模式。
</Tab>
<Tab value='Custom Source'>
Fumadocs 不仅限于 Markdown。对于其他源如 Sanity您可以构建 [自定义内容源](/docs/headless/custom-source)。
</Tab>
</Tabs>
### 自定义 UI
请参阅 [自定义指南](/docs/customisation)。
## 常见问题
您可能遇到的一些常见问题。
<Accordions>
<Accordion id='fix-monorepo-styling' title="如何修复 Monorepo 中样式不应用的问题?">
有时,`fumadocs-ui` 没有安装在您的 Tailwind CSS 配置文件的工作区中(例如,在 monorepo 设置中)。
您必须确保 Tailwind CSS 扫描 `fumadocs-ui` 包,并为 `@source` 提供正确的相对路径。
例如,添加 `../../` 指向根工作区中的 `node_modules` 文件夹。
```css
@import 'tailwindcss';
@import 'fumadocs-ui/css/neutral.css';
@import 'fumadocs-ui/css/preset.css';
/* [!code --] */
@source '../node_modules/fumadocs-ui/dist/**/*.js';
/* [!code ++] */
@source '../../../node_modules/fumadocs-ui/dist/**/*.js';
```
</Accordion>
<Accordion id='change-base-url' title="如何更改 /docs 的基本路由?">
您可以更改文档的基本路由(例如,从 `/docs/page` 更改为 `/info/page`)。
由于 Fumadocs 使用 Next.js App Router您可以简单地重命名路由
<Files>
<Folder name="app/docs" defaultOpen className="opacity-50" disabled>
<File name="layout.tsx" />
</Folder>
<Folder name="app/info" defaultOpen>
<File name="layout.tsx" />
</Folder>
</Files>
并在 `source.ts` 中告诉 Fumadocs 使用新的路由:
```ts title="lib/source.ts"
import { loader } from 'fumadocs-core/source';
export const source = loader({
baseUrl: '/info',
// other options
});
```
</Accordion>
<Accordion id='dynamic-route' title="它使用动态路由,性能会很差吗?">
当配置了 `generateStaticParams` 时Next.js 会将动态路由转换为静态路由。
因此,它与静态页面一样快。
您可以在 Next.js 上启用静态导出,获得静态构建输出。(请注意,路由处理器不适用于静态导出,您必须配置静态搜索)
</Accordion>
<Accordion id='custom-layout-docs-page' title='如何在 /docs 中创建没有文档布局的页面?'>
与在 Next.js App Router 中管理布局相同,从内容目录(`/content/docs`)中删除原始 MDX 文件。
这确保重复的页面不会导致错误。
现在,您可以将页面添加到另一个路由组,该组不是文档布局的后代。
例如,在您的 `app` 文件夹下:
<Files>
<File name="(home)/docs/page.tsx" />
<Folder name="docs">
<File name="layout.tsx" />
<File name="[[...slug]]/page.tsx" />
</Folder>
</Files>
将用您的 `page.tsx` 替换 `/docs` 页面。
</Accordion>
<Accordion id='multi-versions' title="如何实现多版本文档?">
为每个版本使用单独的部署。
在 Vercel 上,可以通过在 GitHub 存储库中为特定版本创建另一个分支来实现。
要链接到其他版本的站点,请使用 Links API 或自定义导航组件。
</Accordion>
<Accordion id='multi-docs' title="如何实现多文档?">
我们建议使用 [侧边栏标签](/docs/navigation/sidebar#sidebar-tabs)。
</Accordion>
</Accordions>
## 了解更多
刚来这里?别担心,我们欢迎您的问题。

View File

@ -0,0 +1,227 @@
---
title: Internationalization
description: Support multiple languages in your documentation
image: /images/blog/post-3.png
date: 2025-03-15T12:00:00.000Z
published: true
categories: [company, product]
author: mksaas
---
<Callout title='Before you get started'>
Fumadocs is not a full-powered i18n library, it manages only its own components and utilities.
You can use other libraries like [next-intl](https://github.com/amannn/next-intl) for the rest of your app.
Read the [Next.js Docs](https://nextjs.org/docs/app/building-your-application/routing/internationalization) to learn more about implementing I18n in Next.js.
</Callout>
## Manual Setup
Define the i18n configurations in a file, we will import it with `@/ilb/i18n` in this guide.
{/* <include cwd meta='title="lib/i18n.ts"'>
../../examples/i18n/lib/i18n.ts
</include> */}
Pass it to the source loader.
```ts title="lib/source.ts"
import { i18n } from '@/lib/i18n';
import { loader } from 'fumadocs-core/source';
export const source = loader({
i18n, // [!code highlight]
// other options
});
```
And update Fumadocs UI layout options.
```tsx title="app/layout.config.tsx"
import { i18n } from '@/lib/i18n';
import type { BaseLayoutProps } from 'fumadocs-ui/layouts/shared';
export function baseOptions(locale: string): BaseLayoutProps {
return {
i18n,
// different props based on `locale`
};
}
```
### Middleware
Create a middleware that redirects users to appropriate locale.
```json doc-gen:file
{
"file": "../../examples/i18n/middleware.ts",
"codeblock": {
"lang": "ts",
"meta": "title=\"middleware.ts\""
}
}
```
See [Middleware](/docs/headless/internationalization#middleware) for customisable options.
> Note that this is optional, you can also use your own middleware or the one provided by i18n libraries.
### Routing
Create a `/app/[lang]` folder, and move all files (e.g. `page.tsx`, `layout.tsx`) from `/app` to the folder.
Wrap the root provider inside `I18nProvider`, and provide available languages & translations to it.
Note that only English translations are provided by default.
```tsx title="app/[lang]/layout.tsx"
import { RootProvider } from 'fumadocs-ui/provider';
import { I18nProvider, type Translations } from 'fumadocs-ui/i18n';
const cn: Partial<Translations> = {
search: 'Translated Content',
// other translations
};
// available languages that will be displayed on UI
// make sure `locale` is consistent with your i18n config
const locales = [
{
name: 'English',
locale: 'en',
},
{
name: 'Chinese',
locale: 'cn',
},
];
export default async function RootLayout({
params,
children,
}: {
params: Promise<{ lang: string }>;
children: React.ReactNode;
}) {
const lang = (await params).lang;
return (
<html lang={lang}>
<body>
<I18nProvider
locale={lang}
locales={locales}
translations={{ cn }[lang]}
>
<RootProvider>{children}</RootProvider>
</I18nProvider>
</body>
</html>
);
}
```
### Pass Locale
Pass the locale to Fumadocs in your pages and layouts.
{/* ```tsx title="/app/[lang]/(home)/layout.tsx" tab="Home Layout"
import type { ReactNode } from 'react';
import { HomeLayout } from 'fumadocs-ui/layouts/home';
import { baseOptions } from '@/app/layout.config';
export default async function Layout({
params,
children,
}: {
params: Promise<{ lang: string }>;
children: ReactNode;
}) {
const { lang } = await params;
return <HomeLayout {...baseOptions(lang)}>{children}</HomeLayout>;
}
```
```tsx title="/app/[lang]/docs/layout.tsx" tab="Docs Layout"
import type { ReactNode } from 'react';
import { source } from '@/lib/source';
import { DocsLayout } from 'fumadocs-ui/layouts/docs';
import { baseOptions } from '@/app/layout.config';
export default async function Layout({
params,
children,
}: {
params: Promise<{ lang: string }>;
children: ReactNode;
}) {
const { lang } = await params;
return (
<DocsLayout {...baseOptions(lang)} tree={source.pageTree[lang]}>
{children}
</DocsLayout>
);
}
```
```ts title="page.tsx" tab="Docs Page"
import { source } from '@/lib/source';
export default async function Page({
params,
}: {
params: Promise<{ lang: string; slug?: string[] }>;
}) {
const { slug, lang } = await params;
// get page
source.getPage(slug); // [!code --]
source.getPage(slug, lang); // [!code ++]
// get pages
source.getPages(); // [!code --]
source.getPages(lang); // [!code ++]
}
``` */}
### Search
Configure i18n on your search solution.
- **Built-in Search (Orama):**
For [Supported Languages](https://docs.orama.com/open-source/supported-languages#officially-supported-languages), no further changes are needed.
Otherwise, additional config is required (e.g. Chinese & Japanese). See [Special Languages](/docs/headless/search/orama#special-languages).
- **Cloud Solutions (e.g. Algolia):**
They usually have official support for multilingual.
## Writing Documents
{/* <include>../../shared/page-conventions.i18n.mdx</include> */}
## Navigation
Fumadocs only handles navigation for its own layouts (e.g. sidebar).
For other places, you can use the `useParams` hook to get the locale from url, and attend it to `href`.
```tsx
import Link from 'next/link';
import { useParams } from 'next/navigation';
const { lang } = useParams();
return <Link href={`/${lang}/another-page`}>This is a link</Link>;
```
In addition, the [`fumadocs-core/dynamic-link`](/docs/headless/components/link#dynamic-hrefs) component supports dynamic hrefs, you can use it to attend the locale prefix.
It is useful for Markdown/MDX content.
```mdx title="content.mdx"
import { DynamicLink } from 'fumadocs-core/dynamic-link';
<DynamicLink href="/[lang]/another-page">This is a link</DynamicLink>
```

View File

@ -0,0 +1,227 @@
---
title: 国际化
description: 在您的文档中支持多种语言
image: /images/blog/post-3.png
date: 2025-03-15T12:00:00.000Z
published: true
categories: [company, product]
author: mksaas
---
<Callout title='开始之前'>
Fumadocs 不是一个功能齐全的 i18n 库,它只管理自己的组件和工具。
您可以使用其他库,如 [next-intl](https://github.com/amannn/next-intl),用于应用程序的其余部分。
阅读 [Next.js 文档](https://nextjs.org/docs/app/building-your-application/routing/internationalization),了解更多关于在 Next.js 中实现 I18n 的信息。
</Callout>
## 手动设置
在一个文件中定义 i18n 配置,我们将在本指南中使用 `@/ilb/i18n` 导入它。
{/* <include cwd meta='title="lib/i18n.ts"'>
../../examples/i18n/lib/i18n.ts
</include> */}
将其传递给源加载器。
```ts title="lib/source.ts"
import { i18n } from '@/lib/i18n';
import { loader } from 'fumadocs-core/source';
export const source = loader({
i18n, // [!code highlight]
// other options
});
```
并更新 Fumadocs UI 布局选项。
```tsx title="app/layout.config.tsx"
import { i18n } from '@/lib/i18n';
import type { BaseLayoutProps } from 'fumadocs-ui/layouts/shared';
export function baseOptions(locale: string): BaseLayoutProps {
return {
i18n,
// different props based on `locale`
};
}
```
### 中间件
创建一个将用户重定向到适当语言环境的中间件。
```json doc-gen:file
{
"file": "../../examples/i18n/middleware.ts",
"codeblock": {
"lang": "ts",
"meta": "title=\"middleware.ts\""
}
}
```
查看[中间件](/docs/headless/internationalization#middleware)了解可自定义选项。
> 请注意,这是可选的,您也可以使用自己的中间件或 i18n 库提供的中间件。
### 路由
创建一个 `/app/[lang]` 文件夹,并将所有文件(例如 `page.tsx`、`layout.tsx`)从 `/app` 移动到该文件夹。
将根提供程序包装在 `I18nProvider` 中,并向其提供可用语言和翻译。
请注意,默认情况下只提供英文翻译。
```tsx title="app/[lang]/layout.tsx"
import { RootProvider } from 'fumadocs-ui/provider';
import { I18nProvider, type Translations } from 'fumadocs-ui/i18n';
const cn: Partial<Translations> = {
search: 'Translated Content',
// other translations
};
// available languages that will be displayed on UI
// make sure `locale` is consistent with your i18n config
const locales = [
{
name: 'English',
locale: 'en',
},
{
name: 'Chinese',
locale: 'cn',
},
];
export default async function RootLayout({
params,
children,
}: {
params: Promise<{ lang: string }>;
children: React.ReactNode;
}) {
const lang = (await params).lang;
return (
<html lang={lang}>
<body>
<I18nProvider
locale={lang}
locales={locales}
translations={{ cn }[lang]}
>
<RootProvider>{children}</RootProvider>
</I18nProvider>
</body>
</html>
);
}
```
### 传递区域设置
在您的页面和布局中将区域设置传递给 Fumadocs。
{/* ```tsx title="/app/[lang]/(home)/layout.tsx" tab="Home Layout"
import type { ReactNode } from 'react';
import { HomeLayout } from 'fumadocs-ui/layouts/home';
import { baseOptions } from '@/app/layout.config';
export default async function Layout({
params,
children,
}: {
params: Promise<{ lang: string }>;
children: ReactNode;
}) {
const { lang } = await params;
return <HomeLayout {...baseOptions(lang)}>{children}</HomeLayout>;
}
```
```tsx title="/app/[lang]/docs/layout.tsx" tab="Docs Layout"
import type { ReactNode } from 'react';
import { source } from '@/lib/source';
import { DocsLayout } from 'fumadocs-ui/layouts/docs';
import { baseOptions } from '@/app/layout.config';
export default async function Layout({
params,
children,
}: {
params: Promise<{ lang: string }>;
children: ReactNode;
}) {
const { lang } = await params;
return (
<DocsLayout {...baseOptions(lang)} tree={source.pageTree[lang]}>
{children}
</DocsLayout>
);
}
```
```ts title="page.tsx" tab="Docs Page"
import { source } from '@/lib/source';
export default async function Page({
params,
}: {
params: Promise<{ lang: string; slug?: string[] }>;
}) {
const { slug, lang } = await params;
// get page
source.getPage(slug); // [!code --]
source.getPage(slug, lang); // [!code ++]
// get pages
source.getPages(); // [!code --]
source.getPages(lang); // [!code ++]
}
``` */}
### 搜索
在您的搜索解决方案上配置 i18n。
- **内置搜索 (Orama)**
对于[支持的语言](https://docs.orama.com/open-source/supported-languages#officially-supported-languages),无需进一步更改。
否则,需要额外配置(例如中文和日语)。请参阅[特殊语言](/docs/headless/search/orama#special-languages)。
- **云解决方案(例如 Algolia**
它们通常官方支持多语言。
## 编写文档
{/* <include>../../shared/page-conventions.i18n.mdx</include> */}
## 导航
Fumadocs 只处理其自己的布局(例如侧边栏)的导航。
对于其他地方,您可以使用 `useParams` 钩子从 url 获取区域设置,并将其添加到 `href`。
```tsx
import Link from 'next/link';
import { useParams } from 'next/navigation';
const { lang } = useParams();
return <Link href={`/${lang}/another-page`}>This is a link</Link>;
```
另外,[`fumadocs-core/dynamic-link`](/docs/headless/components/link#dynamic-hrefs) 组件支持动态 hrefs您可以使用它来添加区域设置前缀。
这对于 Markdown/MDX 内容很有用。
```mdx title="content.mdx"
import { DynamicLink } from 'fumadocs-core/dynamic-link';
<DynamicLink href="/[lang]/another-page">This is a link</DynamicLink>
```

View File

@ -0,0 +1,198 @@
---
title: Manual Installation
description: Create a new fumadocs project from scratch.
image: /images/blog/post-4.png
date: 2025-03-14T12:00:00.000Z
published: true
categories: [company, product]
author: mkdirs
---
> Read the [Quick Start](/docs) guide first for basic concept.
## Getting Started
Create a new Next.js application with `create-next-app`, and install required packages.
```package-install
fumadocs-ui fumadocs-core
```
### Content Source
Fumadocs supports different content sources, you can choose one you prefer.
There is a list of officially supported sources:
- [Setup Fumadocs MDX](/docs/mdx)
- [Setup Content Collections](/docs/headless/content-collections)
Make sure to configure the library correctly following their setup guide before continuing, we will import the source adapter using `@/lib/source.ts` in this guide.
### Root Layout
Wrap the entire application inside [Root Provider](/docs/layouts/root-provider), and add required styles to `body`.
```tsx
import { RootProvider } from 'fumadocs-ui/provider';
import type { ReactNode } from 'react';
export default function Layout({ children }: { children: ReactNode }) {
return (
<html lang="en" suppressHydrationWarning>
<body
// you can use Tailwind CSS too
style={{
display: 'flex',
flexDirection: 'column',
minHeight: '100vh',
}}
>
<RootProvider>{children}</RootProvider>
</body>
</html>
);
}
```
### Styles
Setup Tailwind CSS v4 on your Next.js app, add the following to `global.css`.
```css title="Tailwind CSS"
@import 'tailwindcss';
@import 'fumadocs-ui/css/neutral.css';
@import 'fumadocs-ui/css/preset.css';
/* path of `fumadocs-ui` relative to the CSS file */
@source '../node_modules/fumadocs-ui/dist/**/*.js';
```
> It doesn't come with a default font, you may choose one from `next/font`.
### Layout
Create a `app/layout.config.tsx` file to put the shared options for our layouts.
```json doc-gen:file
{
"file": "../../examples/next-mdx/app/layout.config.tsx",
"codeblock": {
"meta": "title=\"app/layout.config.tsx\""
}
}
```
Create a folder `/app/docs` for our docs, and give it a proper layout.
```json doc-gen:file
{
"file": "../../examples/next-mdx/app/docs/layout.tsx",
"codeblock": {
"meta": "title=\"app/docs/layout.tsx\""
}
}
```
> `pageTree` refers to Page Tree, it should be provided by your content source.
### Page
Create a catch-all route `/app/docs/[[...slug]]` for docs pages.
In the page, wrap your content in the [Page](/docs/layouts/page) component.
It may vary depending on your content source. You should configure static rendering with `generateStaticParams` and metadata with `generateMetadata`.
<Tabs items={['Fumadocs MDX', 'Content Collections']}>
<Tab value='Fumadocs MDX'>
```json doc-gen:file
{
"file": "../../examples/next-mdx/app/docs/[[...slug]]/page.tsx",
"codeblock": {
"meta": "title=\"app/docs/[[...slug]]/page.tsx\" tab=\"Fumadocs MDX\""
}
}
```
</Tab>
<Tab value='Content Collections'>
```json doc-gen:file
{
"file": "../../examples/content-collections/app/docs/[[...slug]]/page.tsx",
"codeblock": {
"meta": "title=\"app/docs/[[...slug]]/page.tsx\" tab=\"Content Collections\""
}
}
```
</Tab>
</Tabs>
### Search
Use the default document search based on Orama.
<Tabs items={['Fumadocs MDX', 'Content Collections']}>
<Tab value='Fumadocs MDX'>
```json doc-gen:file
{
"file": "../../examples/next-mdx/app/api/search/route.ts",
"codeblock": {
"meta": "title=\"app/api/search/route.ts\" tab=\"Fumadocs MDX\""
}
}
```
</Tab>
<Tab value='Content Collections'>
```json doc-gen:file
{
"file": "../../examples/content-collections/app/api/search/route.ts",
"codeblock": {
"meta": "title=\"app/api/search/route.ts\" tab=\"Content Collections\""
}
}
```
</Tab>
</Tabs>
Learn more about [Document Search](/docs/headless/search).
### Done
You can start the dev server and create MDX files.
```mdx title="content/docs/index.mdx"
---
title: Hello World
---
## Introduction
I love Anime.
```
## Customise
You can use [Home Layout](/docs/layouts/home-layout) for other pages of the site, it includes a navbar with theme toggle.
## Deploying
It should work out-of-the-box with Vercel & Netlify.
### Docker Deployment
If you want to deploy your Fumadocs app using Docker with **Fumadocs MDX configured**, make sure to add the `source.config.ts` file to the `WORKDIR` in the Dockerfile.
The following snippet is taken from the official [Next.js Dockerfile Example](https://github.com/vercel/next.js/blob/canary/examples/with-docker/Dockerfile):
```zsh title="Dockerfile"
WORKDIR /app
# Install dependencies based on the preferred package manager
COPY package.json yarn.lock* package-lock.json* pnpm-lock.yaml* .npmrc* source.config.ts ./
```
This ensures Fumadocs MDX can access your configuration file during builds.

View File

@ -0,0 +1,196 @@
---
title: 手动安装
description: 从零开始创建一个新的 Fumadocs 项目
image: /images/blog/post-4.png
date: 2025-03-14T12:00:00.000Z
published: true
categories: [company, product]
author: mkdirs
---
> 请先阅读[快速入门](/docs)指南了解基本概念。
## 入门
使用 `create-next-app` 创建一个新的 Next.js 应用程序,并安装所需的包。
```package-install
fumadocs-ui fumadocs-core
```
### 内容源
Fumadocs 支持不同的内容源,您可以选择您喜欢的一种。
以下是官方支持的源列表:
- [设置 Fumadocs MDX](/docs/mdx)
- [设置 Content Collections](/docs/headless/content-collections)
请确保在继续之前按照其设置指南正确配置库,我们将在本指南中使用 `@/lib/source.ts` 导入源适配器。
### 根布局
将整个应用程序包装在 [Root Provider](/docs/layouts/root-provider) 中,并为 `body` 添加所需的样式。
```tsx
import { RootProvider } from 'fumadocs-ui/provider';
import type { ReactNode } from 'react';
export default function Layout({ children }: { children: ReactNode }) {
return (
<html lang="en" suppressHydrationWarning>
<body
// you can use Tailwind CSS too
style={{
display: 'flex',
flexDirection: 'column',
minHeight: '100vh',
}}
>
<RootProvider>{children}</RootProvider>
</body>
</html>
);
}
```
### 样式
在您的 Next.js 应用程序上设置 Tailwind CSS v4将以下内容添加到 `global.css`。
```css title="Tailwind CSS"
@import 'tailwindcss';
@import 'fumadocs-ui/css/neutral.css';
@import 'fumadocs-ui/css/preset.css';
/* path of `fumadocs-ui` relative to the CSS file */
@source '../node_modules/fumadocs-ui/dist/**/*.js';
```
> 它不附带默认字体,您可以从 `next/font` 中选择一个。
### 布局
创建一个 `app/layout.config.tsx` 文件,放置我们布局的共享选项。
```json doc-gen:file
{
"file": "../../examples/next-mdx/app/layout.config.tsx",
"codeblock": {
"meta": "title=\"app/layout.config.tsx\""
}
}
```
为我们的文档创建一个文件夹 `/app/docs`,并给它一个适当的布局。
```json doc-gen:file
{
"file": "../../examples/next-mdx/app/docs/layout.tsx",
"codeblock": {
"meta": "title=\"app/docs/layout.tsx\""
}
}
```
> `pageTree` 指的是页面树,应该由您的内容源提供。
### 页面
为文档页面创建一个捕获所有路由 `/app/docs/[[...slug]]`。
在页面中,将您的内容包装在 [Page](/docs/layouts/page) 组件中。
这可能因您的内容源而异。您应该使用 `generateStaticParams` 配置静态渲染,并使用 `generateMetadata` 配置元数据。
<Tabs items={['Fumadocs MDX', 'Content Collections']}>
<Tab value='Fumadocs MDX'>
```json doc-gen:file
{
"file": "../../examples/next-mdx/app/docs/[[...slug]]/page.tsx",
"codeblock": {
"meta": "title=\"app/docs/[[...slug]]/page.tsx\" tab=\"Fumadocs MDX\""
}
}
```
</Tab>
<Tab value='Content Collections'>
```json doc-gen:file
{
"file": "../../examples/content-collections/app/docs/[[...slug]]/page.tsx",
"codeblock": {
"meta": "title=\"app/docs/[[...slug]]/page.tsx\" tab=\"Content Collections\""
}
}
```
</Tab>
</Tabs>
### 搜索
使用基于 Orama 的默认文档搜索。
<Tabs items={['Fumadocs MDX', 'Content Collections']}>
<Tab value='Fumadocs MDX'>
```json doc-gen:file
{
"file": "../../examples/next-mdx/app/api/search/route.ts",
"codeblock": {
"meta": "title=\"app/api/search/route.ts\" tab=\"Fumadocs MDX\""
}
}
```
</Tab>
<Tab value='Content Collections'>
```json doc-gen:file
{
"file": "../../examples/content-collections/app/api/search/route.ts",
"codeblock": {
"meta": "title=\"app/api/search/route.ts\" tab=\"Content Collections\""
}
}
```
</Tab>
</Tabs>
了解更多关于[文档搜索](/docs/headless/search)的信息。
### 完成
您可以启动开发服务器并创建 MDX 文件。
```mdx title="content/docs/index.mdx"
---
title: Hello World
---
## Introduction
I love Anime.
```
## 自定义
您可以为网站的其他页面使用 [Home Layout](/docs/layouts/home-layout),它包含一个带有主题切换的导航栏。
## 部署
它应该在 Vercel 和 Netlify 上开箱即用。
### Docker 部署
如果您想使用 Docker 部署您的 Fumadocs 应用程序,并且已**配置了 Fumadocs MDX**,请确保将 `source.config.ts` 文件添加到 Dockerfile 中的 `WORKDIR`。
以下片段取自官方 [Next.js Dockerfile 示例](https://github.com/vercel/next.js/blob/canary/examples/with-docker/Dockerfile)
```zsh title="Dockerfile"
WORKDIR /app
# Install dependencies based on the preferred package manager
COPY package.json yarn.lock* package-lock.json* pnpm-lock.yaml* .npmrc* source.config.ts ./
```
这确保 Fumadocs MDX 在构建期间可以访问您的配置文件。

385
content/blog/markdown.mdx Normal file
View File

@ -0,0 +1,385 @@
---
title: Markdown
description: How to write documents
image: /images/blog/post-5.png
date: 2025-03-05T12:00:00.000Z
published: true
categories: [news, company]
author: mkdirs
---
## Introduction
Fumadocs provides many useful extensions to MDX, a markup language. Here is a brief introduction to the default MDX syntax of Fumadocs UI.
> MDX is not the only supported format of Fumadocs. In fact, you can use any renderers such as `next-mdx-remote` or CMS.
## Markdown
We use GFM (GitHub Flavored Markdown), a superset of Markdown (CommonMark).
See [GFM Specification](https://github.github.com/gfm).
````md
# Heading
## Heading
### Heading
#### Heading
Hello World, **Bold**, _Italic_, ~~Hidden~~
```js
console.log('Hello World');
```
1. First
2. Second
3. Third
- Item 1
- Item 2
> Quote here
![alt](/image.png)
| Table | Description |
| ----- | ----------- |
| Hello | World |
````
### Auto Links
Internal links use the `next/link` component to allow prefetching and avoid hard-reload.
External links will get the default `rel="noreferrer noopener" target="_blank"` attributes for security.
```mdx
[My Link](https://github.github.com/gfm)
This also works: https://github.github.com/gfm.
```
## MDX
MDX is a superset of Markdown, with support of JSX syntax.
It allows you to import components, and use them right in the document, or even export values.
```mdx
import { Component } from './component';
<Component name="Hello" />
```
see [MDX Syntax](https://mdxjs.com/docs/what-is-mdx/#mdx-syntax) to learn more.
### Cards
Useful for adding links, it is included by default.
```mdx
<Cards>
<Card
href="https://nextjs.org/docs/app/building-your-application/data-fetching/fetching-caching-and-revalidating"
title="Fetching, Caching, and Revalidating"
>
Learn more about caching in Next.js
</Card>
</Cards>
```
<Cards>
<Card
href="https://nextjs.org/docs/app/building-your-application/data-fetching/fetching-caching-and-revalidating"
title="Fetching, Caching, and Revalidating"
>
Learn more about caching in Next.js
</Card>
</Cards>
#### Icon
You can specify an icon to cards.
```mdx
import { HomeIcon } from 'lucide-react';
<Cards>
<Card icon={<HomeIcon />} href="/" title="Home">
Go back to home
</Card>
</Cards>
```
<Cards>
<Card icon={<HomeIcon />} href="/" title="Go back to home">
The home page of Fumadocs.
</Card>
</Cards>
#### Without href
```mdx
<Cards>
<Card title="Fetching, Caching, and Revalidating">
Learn more about `fetch` in Next.js.
</Card>
</Cards>
```
<Cards>
<Card title="Fetching, Caching, and Revalidating">
Learn more about `fetch` in Next.js.
</Card>
</Cards>
### Callouts
Useful for adding tips/warnings, it is included by default.
```mdx
<Callout>Hello World</Callout>
```
<Callout>Hello World</Callout>
#### Title
Specify a callout title.
```mdx
<Callout title="Title">Hello World</Callout>
```
<Callout title="Title">Hello World</Callout>
#### Types
You can specify the type of callout.
- `info` (default)
- `warn`
- `error`
```mdx
<Callout title="Title" type="error">
Hello World
</Callout>
```
<Callout title="Title" type="error">
Hello World
</Callout>
### Customise Components
See [all MDX components and available options](/docs/mdx).
## Headings
An anchor is automatically applied to each heading, it sanitizes invalid characters like spaces. (e.g. `Hello World` to `hello-world`)
```md
# Hello `World`
```
### TOC Settings
The table of contents (TOC) will be generated based on headings, you can also customise the effects of headings:
```md
# Heading [!toc]
This heading will be hidden from TOC.
# Another Heading [toc]
This heading will **only** be visible in TOC, you can use it to add additional TOC items.
Like headings rendered in a React component:
<MyComp />
```
### Custom Anchor
You can add `[#slug]` to customise heading anchors.
```md
# heading [#my-heading-id]
```
You can also chain it with TOC settings like:
```md
# heading [toc] [#my-heading-id]
```
To link people to a specific heading, add the heading id to hash fragment: `/page#my-heading-id`.
## Frontmatter
We support YAML frontmatter. It is a way to specify common information of the document (e.g. title).
Place it at the top of document.
```mdx
---
title: Hello World
---
## Title
```
See [Page Conventions](/docs/page-conventions#frontmatter) for a list of properties available for frontmatter.
## Codeblock
Syntax Highlighting is supported by default using [Rehype Code](/docs/headless/mdx/rehype-code).
````mdx
```js
console.log('Hello World');
```
````
You can add a title to the codeblock.
````mdx
```js title="My Title"
console.log('Hello World');
```
````
### Highlight Lines
You can highlight specific lines by adding `[!code highlight]`.
````md
```tsx
<div>Hello World</div> // [\!code highlight]
<div>Hello World</div>
<div>Goodbye</div>
<div>Hello World</div>
```
````
### Highlight Words
You can highlight a specific word by adding `[!code word:<match>]`.
````md
```js
// [\!code word:config]
const config = {
reactStrictMode: true,
};
```
````
### Diffs
````mdx
```ts
console.log('hewwo'); // [\!code --]
console.log('hello'); // [\!code ++]
```
````
```ts
console.log('hewwo'); // [!code --]
console.log('hello'); // [!code ++]
```
### Tab Groups
You can use code blocks with the `<Tab />` component.
````mdx
import { Tab, Tabs } from 'fumadocs-ui/components/tabs';
<Tabs items={['Tab 1', 'Tab 2']}>
<Tab value='Tab 1'>
```ts
console.log('A');
```
</Tab>
<Tab value='Tab 2'>
```ts
console.log('B');
```
</Tab>
</Tabs>
````
> Note that you can add MDX components instead of importing them in MDX files.
<Tabs items={['Tab 1', 'Tab 2']}>
<Tab value='Tab 1'>
```ts
console.log('A');
```
</Tab>
<Tab value='Tab 2'>
```ts
console.log('B');
```
</Tab>
</Tabs>
### Using Typescript Twoslash
Write Typescript codeblocks with hover type information and detected types errors.
Not enabled by default. See [Twoslash](/docs/twoslash).
## Images
All built-in content sources handle images properly.
Images are automatically optimized for `next/image`.
```mdx
![Image](/image.png)
```
![Image](/images/blog/post-1.png)
## Optional
Some optional plugins you can enable.
### Math Equations
Write math equations with TeX.
````md
```math
f(x) = x * e^{2 pi i \xi x}
```
````
```math
f(x) = x * e^{2 pi i \xi x}
```
To enable, see [Math Integration](/docs/math).
### Package Install
Generate code blocks for installing packages via package managers (JS/Node.js).
````md
```package-install
npm i next -D
```
````
```package-install
npm i next -D
```
To enable, see [Remark Install](/docs/headless/mdx/install).
### More
You can see [a list of plugins](/docs/headless/mdx) supported by Fumadocs.

View File

@ -0,0 +1,345 @@
---
title: Markdown
description: 如何撰写文档
image: /images/blog/post-5.png
date: 2025-03-05T12:00:00.000Z
published: true
categories: [news, company]
author: mkdirs
---
## 介绍
Fumadocs 为 MDX一种标记语言提供了许多有用的扩展。以下是 Fumadocs UI 默认 MDX 语法的简要介绍。
> MDX 不是 Fumadocs 唯一支持的格式。实际上,您可以使用任何渲染器,如 `next-mdx-remote` 或 CMS。
## Markdown
我们使用 GFMGitHub 风格的 Markdown这是 MarkdownCommonMark的超集。
参见 [GFM 规范](https://github.github.com/gfm)。
````md
# Heading
## Heading
### Heading
#### Heading
Hello World, **Bold**, _Italic_, ~~Hidden~~
```js
console.log('Hello World');
```
1. First
2. Second
3. Third
- Item 1
- Item 2
> Quote here
![alt](/image.png)
| Table | Description |
| ----- | ----------- |
| Hello | World |
````
### 自动链接
内部链接使用 `next/link` 组件,允许预取并避免硬重载。
外部链接将获得默认的 `rel="noreferrer noopener" target="_blank"` 属性以增强安全性。
```mdx
[My Link](https://github.github.com/gfm)
This also works: https://github.github.com/gfm.
```
## MDX
MDX 是 Markdown 的超集,支持 JSX 语法。
它允许您导入组件,并直接在文档中使用它们,甚至导出值。
```mdx
import { Component } from './component';
<Component name="Hello" />
```
参见 [MDX 语法](https://mdxjs.com/docs/what-is-mdx/#mdx-syntax) 了解更多信息。
### 卡片
对于添加链接很有用,默认包含。
```mdx
<Cards>
<Card
href="https://nextjs.org/docs/app/building-your-application/data-fetching/fetching-caching-and-revalidating"
title="Fetching, Caching, and Revalidating"
>
Learn more about caching in Next.js
</Card>
</Cards>
```
<Cards>
<Card
href="https://nextjs.org/docs/app/building-your-application/data-fetching/fetching-caching-and-revalidating"
title="Fetching, Caching, and Revalidating"
>
Learn more about caching in Next.js
</Card>
</Cards>
#### 图标
您可以为卡片指定图标。
```mdx
import { HomeIcon } from 'lucide-react';
<Cards>
<Card icon={<HomeIcon />} href="/" title="Home">
Go back to home
</Card>
</Cards>
```
<Cards>
<Card icon={<HomeIcon />} href="/" title="Go back to home">
The home page of Fumadocs.
</Card>
</Cards>
#### 无 href
```mdx
<Cards>
<Card title="Fetching, Caching, and Revalidating">
Learn more about `fetch` in Next.js.
</Card>
</Cards>
```
<Cards>
<Card title="Fetching, Caching, and Revalidating">
Learn more about `fetch` in Next.js.
</Card>
</Cards>
### 提示框
对于添加提示/警告很有用,默认包含。
```mdx
<Callout>Hello World</Callout>
```
<Callout>Hello World</Callout>
#### 标题
指定提示框标题。
```mdx
<Callout title="Title">Hello World</Callout>
```
<Callout title="Title">Hello World</Callout>
#### 类型
您可以指定提示框的类型。
- `info`(默认)
- `warn`
- `error`
```mdx
<Callout title="Title" type="error">
Hello World
</Callout>
```
<Callout title="Title" type="error">
Hello World
</Callout>
### 自定义组件
参见[所有 MDX 组件和可用选项](/docs/mdx)。
## 标题
每个标题会自动应用锚点,它会清理空格等无效字符。(例如,`Hello World` 变为 `hello-world`
```md
# Hello `World`
```
### 目录设置
目录 (TOC) 将基于标题生成,您还可以自定义标题的效果:
```md
# Heading [!toc]
This heading will be hidden from TOC.
# Another Heading [toc]
This heading will **only** be visible in TOC, you can use it to add additional TOC items.
Like headings rendered in a React component:
<MyComp />
```
### 自定义锚点
您可以添加 `[#slug]` 来自定义标题锚点。
```md
# heading [#my-heading-id]
```
您也可以将其与目录设置链接起来,例如:
```md
# heading [toc] [#my-heading-id]
```
要将人们链接到特定标题,请将标题 ID 添加到哈希片段:`/page#my-heading-id`。
## 前言
我们支持 YAML 前言。这是一种指定文档常见信息(例如标题)的方式。
将其放在文档顶部。
```mdx
---
title: Hello World
---
## Title
```
有关前言可用属性的列表,请参见[页面约定](/docs/page-conventions#frontmatter)。
## 代码块
默认使用 [Rehype Code](/docs/headless/mdx/rehype-code) 支持语法高亮。
````mdx
```js
console.log('Hello World');
```
````
您可以为代码块添加标题。
````mdx
```js title="My Title"
console.log('Hello World');
```
````
### 高亮行
````md
```tsx
<div>Hello World</div> // [\!code highlight]
<div>Hello World</div>
<div>Goodbye</div>
<div>Hello World</div>
```
````
### 高亮单词
您可以通过添加 `[!code word:<match>]` 来高亮特定单词。
````md
```js
// [\!code word:config]
const config = {
reactStrictMode: true,
};
```
````
### 差异
````mdx
```ts
console.log('hewwo'); // [\!code --]
console.log('hello'); // [\!code ++]
```
````
```ts
console.log('hewwo'); // [!code --]
console.log('hello'); // [!code ++]
```
### 标签组
您可以使用 `<Tab />` 组件与代码块一起使用。
````mdx
import { Tab, Tabs } from 'fumadocs-ui/components/tabs';
<Tabs items={['Tab 1', 'Tab 2']}>
<Tab value='Tab 1'>
```ts
console.log('A');
```
</Tab>
<Tab value='Tab 2'>
```ts
console.log('B');
```
</Tab>
</Tabs>
````
> 注意,您可以在 MDX 文件中添加 MDX 组件,而不必导入它们。
<Tabs items={['Tab 1', 'Tab 2']}>
<Tab value='Tab 1'>
```ts
console.log('A');
```
</Tab>
<Tab value='Tab 2'>
```ts
console.log('B');
```
</Tab>
</Tabs>
### 使用 Typescript Twoslash
编写带有悬停类型信息和检测到类型错误的 Typescript 代码块。
默认情况下未启用。参见 [Twoslash](/docs/twoslash)。
## 图片
所有内置内容源都能正确处理图片。
图片会自动为 `next/image` 优化。
```mdx
![Image](/image.png)
```
## 可选功能
一些您可以启用的可选插件。

280
content/blog/search.mdx Normal file
View File

@ -0,0 +1,280 @@
---
title: Search
description: Implement document search in your docs
image: /images/blog/post-6.png
date: 2025-02-15T12:00:00.000Z
published: true
categories: [company, news]
author: mksaas
---
Fumadocs UI provides a good-looking search UI for your docs, the search functionality is instead provided and documented on Fumadocs Core.
See [Document Search](/docs/headless/search).
## Search UI
Open with <kbd>⌘</kbd> <kbd>K</kbd> or <kbd>Ctrl</kbd> <kbd>K</kbd>.
### Configurations
You can customize search UI from the [Root Provider](/docs/layouts/root-provider) component in root layout.
When not specified, it uses the Default [`fetch` Search Client](/docs/headless/search/orama) powered by Orama.
### Custom Links
Add custom link items to search dialog.
They are shown as fallbacks when the query is empty.
```tsx title="app/layout.tsx"
import { RootProvider } from 'fumadocs-ui/root-provider';
<RootProvider
search={{
links: [
['Home', '/'],
['Docs', '/docs'],
],
}}
>
{children}
</RootProvider>;
```
### Disable Search
To opt-out of document search, disable it from root provider.
```tsx
import { RootProvider } from 'fumadocs-ui/root-provider';
<RootProvider
search={{
enabled: false,
}}
>
{children}
</RootProvider>;
```
### Hot Keys
Customise the hot keys to trigger search dialog.
```tsx
import { RootProvider } from 'fumadocs-ui/root-provider';
<RootProvider
search={{
hotKey: [
{
display: 'K',
key: 'k', // key code, or a function determining whether the key is pressed
},
],
}}
>
{children}
</RootProvider>;
```
### Tag Filter
Add UI to change filters.
Make sure to configure [Tag Filter](/docs/headless/search/orama#tag-filter) on search server first.
```tsx
import { RootProvider } from 'fumadocs-ui/root-provider';
<RootProvider
search={{
options: {
defaultTag: 'value',
tags: [
{
name: 'Tag Name',
value: 'value',
},
],
},
}}
>
{children}
</RootProvider>;
```
### Search Options
Pass options to the search client, like changing the API endpoint for Orama search server:
```tsx
import { RootProvider } from 'fumadocs-ui/root-provider';
<RootProvider
search={{
options: {
api: '/api/search/docs',
},
}}
>
{children}
</RootProvider>;
```
### Replace Search Dialog
You can replace the default Search Dialog with:
```tsx title="components/search.tsx"
'use client';
import SearchDialog from 'fumadocs-ui/components/dialog/search-default';
import type { SharedProps } from 'fumadocs-ui/components/dialog/search';
export default function CustomDialog(props: SharedProps) {
// your own logic here
return <SearchDialog {...props} />;
}
```
To pass it to the Root Provider, you need a wrapper with `use client` directive.
```tsx title="provider.tsx"
'use client';
import { RootProvider } from 'fumadocs-ui/provider';
import dynamic from 'next/dynamic';
import type { ReactNode } from 'react';
const SearchDialog = dynamic(() => import('@/components/search')); // lazy load
export function Provider({ children }: { children: ReactNode }) {
return (
<RootProvider
search={{
SearchDialog,
}}
>
{children}
</RootProvider>
);
}
```
Use it instead of your previous Root Provider
```tsx title="layout.tsx"
import { Provider } from './provider';
import type { ReactNode } from 'react';
export default function Layout({ children }: { children: ReactNode }) {
return (
<html lang="en">
<body>
<Provider>{children}</Provider>
</body>
</html>
);
}
```
## Other Solutions
### Algolia
For the setup guide, see [Integrate Algolia Search](/docs/headless/search/algolia).
While generally we recommend building your own search with their client-side
SDK, you can also plug the built-in dialog interface.
```tsx title="components/search.tsx"
'use client';
import algo from 'algoliasearch/lite';
import type { SharedProps } from 'fumadocs-ui/components/dialog/search';
import SearchDialog from 'fumadocs-ui/components/dialog/search-algolia';
const client = algo('appId', 'apiKey');
const index = client.initIndex('indexName');
export default function CustomSearchDialog(props: SharedProps) {
return <SearchDialog index={index} {...props} />;
}
```
1. Replace `appId`, `apiKey` and `indexName` with your desired values.
2. [Replace the default search dialog](#replace-search-dialog) with your new component.
<Callout title="Note" className='mt-4'>
The built-in implementation doesn't use instant search (their official
javascript client).
</Callout>
#### Tag Filter
Same as default search client, you can configure [Tag Filter](/docs/headless/search/algolia#tag-filter) on the dialog.
```tsx title="components/search.tsx"
import SearchDialog from 'fumadocs-ui/components/dialog/search-algolia';
<SearchDialog
defaultTag="value"
tags={[
{
name: 'Tag Name',
value: 'value',
},
]}
/>;
```
### Orama Cloud
For the setup guide, see [Integrate Orama Cloud](/docs/headless/search/orama-cloud).
```tsx title="components/search.tsx"
'use client';
import { OramaClient } from '@oramacloud/client';
import type { SharedProps } from 'fumadocs-ui/components/dialog/search';
import SearchDialog from 'fumadocs-ui/components/dialog/search-orama';
const client = new OramaClient({
endpoint: 'endpoint',
api_key: 'apiKey',
});
export default function CustomSearchDialog(props: SharedProps) {
return <SearchDialog {...props} client={client} showOrama />;
}
```
1. Replace `endpoint`, `apiKey` with your desired values.
2. [Replace the default search dialog](#replace-search-dialog) with your new component.
### Community Integrations
A list of integrations maintained by community.
- [Trieve Search](/docs/headless/search/trieve)
## Built-in UI
If you want to use the built-in search dialog UI instead of building your own,
you may use the `SearchDialog` component.
```tsx
import {
SearchDialog,
type SharedProps,
} from 'fumadocs-ui/components/dialog/search';
export default function CustomSearchDialog(props: SharedProps) {
return <SearchDialog {...props} />;
}
```
<Callout type="warn" title="Unstable">
It is an internal API, might break during iterations
</Callout>

252
content/blog/search.zh.mdx Normal file
View File

@ -0,0 +1,252 @@
---
title: 搜索
description: 在您的文档中实现文档搜索
image: /images/blog/post-6.png
date: 2025-02-15T12:00:00.000Z
published: true
categories: [company, news]
author: mksaas
---
Fumadocs UI 为您的文档提供了一个美观的搜索界面,而搜索功能则由 Fumadocs Core 提供和记录。
参见[文档搜索](/docs/headless/search)。
## 搜索 UI
使用 <kbd>⌘</kbd> <kbd>K</kbd> 或 <kbd>Ctrl</kbd> <kbd>K</kbd> 打开。
### 配置
您可以通过根布局中的 [Root Provider](/docs/layouts/root-provider) 组件自定义搜索 UI。
当未指定时,它使用由 Orama 提供支持的默认 [`fetch` 搜索客户端](/docs/headless/search/orama)。
### 自定义链接
向搜索对话框添加自定义链接项。
当查询为空时,它们会显示为备选项。
```tsx title="app/layout.tsx"
import { RootProvider } from 'fumadocs-ui/root-provider';
<RootProvider
search={{
links: [
['Home', '/'],
['Docs', '/docs'],
],
}}
>
{children}
</RootProvider>;
```
### 禁用搜索
要禁用文档搜索,请在根提供程序中禁用它。
```tsx
import { RootProvider } from 'fumadocs-ui/root-provider';
<RootProvider
search={{
enabled: false,
}}
>
{children}
</RootProvider>;
```
### 热键
自定义触发搜索对话框的热键。
```tsx
import { RootProvider } from 'fumadocs-ui/root-provider';
<RootProvider
search={{
hotKey: [
{
display: 'K',
key: 'k', // key code, or a function determining whether the key is pressed
},
],
}}
>
{children}
</RootProvider>;
```
### 标签过滤器
添加 UI 以更改过滤器。
确保首先在搜索服务器上配置[标签过滤器](/docs/headless/search/orama#tag-filter)。
```tsx
import { RootProvider } from 'fumadocs-ui/root-provider';
<RootProvider
search={{
options: {
defaultTag: 'value',
tags: [
{
name: 'Tag Name',
value: 'value',
},
],
},
}}
>
{children}
</RootProvider>;
```
### 搜索选项
向搜索客户端传递选项,例如更改 Orama 搜索服务器的 API 端点:
```tsx
import { RootProvider } from 'fumadocs-ui/root-provider';
<RootProvider
search={{
options: {
api: '/api/search/docs',
},
}}
>
{children}
</RootProvider>;
```
### 替换搜索对话框
您可以用以下内容替换默认搜索对话框:
```tsx title="components/search.tsx"
'use client';
import SearchDialog from 'fumadocs-ui/components/dialog/search-default';
import type { SharedProps } from 'fumadocs-ui/components/dialog/search';
export default function CustomDialog(props: SharedProps) {
// your own logic here
return <SearchDialog {...props} />;
}
```
要将其传递给 Root Provider您需要一个带有 `use client` 指令的包装器。
```tsx title="provider.tsx"
'use client';
import { RootProvider } from 'fumadocs-ui/provider';
import dynamic from 'next/dynamic';
import type { ReactNode } from 'react';
const SearchDialog = dynamic(() => import('@/components/search')); // lazy load
export function Provider({ children }: { children: ReactNode }) {
return (
<RootProvider
search={{
SearchDialog,
}}
>
{children}
</RootProvider>
);
}
```
使用它替代您之前的 Root Provider
```tsx title="layout.tsx"
import { Provider } from './provider';
import type { ReactNode } from 'react';
export default function Layout({ children }: { children: ReactNode }) {
return (
<html lang="en">
<body>
<Provider>{children}</Provider>
</body>
</html>
);
}
```
## 其他解决方案
### Algolia
关于设置指南,请参见[集成 Algolia 搜索](/docs/headless/search/algolia)。
虽然我们通常建议使用他们的客户端 SDK 构建您自己的搜索,但您也可以插入内置的对话框接口。
```tsx title="components/search.tsx"
'use client';
import algo from 'algoliasearch/lite';
import type { SharedProps } from 'fumadocs-ui/components/dialog/search';
import SearchDialog from 'fumadocs-ui/components/dialog/search-algolia';
const client = algo('appId', 'apiKey');
const index = client.initIndex('indexName');
export default function CustomSearchDialog(props: SharedProps) {
return <SearchDialog index={index} {...props} />;
}
```
1. 将 `appId`、`apiKey` 和 `indexName` 替换为您想要的值。
2. 用您的新组件[替换默认搜索对话框](#replace-search-dialog)。
<Callout title="注意" className='mt-4'>
内置实现不使用即时搜索(他们的官方 JavaScript 客户端)。
</Callout>
#### 标签过滤器
与默认搜索客户端相同,您可以在对话框上配置[标签过滤器](/docs/headless/search/algolia#tag-filter)。
```tsx title="components/search.tsx"
import SearchDialog from 'fumadocs-ui/components/dialog/search-algolia';
<SearchDialog
defaultTag="value"
tags={[
{
name: 'Tag Name',
value: 'value',
},
]}
/>;
```
### Orama Cloud
关于设置指南,请参见[集成 Orama Cloud](/docs/headless/search/orama-cloud)。
```tsx title="components/search.tsx"
'use client';
import { OramaClient } from '@oramacloud/client';
import type { SharedProps } from 'fumadocs-ui/components/dialog/search';
import SearchDialog from 'fumadocs-ui/components/dialog/search-orama';
const client = new OramaClient({
endpoint: 'endpoint',
api_key: 'apiKey',
});
export default function CustomSearchDialog(props: SharedProps) {
return <SearchDialog {...props} client={client} showOrama />;
}
```
1. 将 `endpoint`、`apiKey` 替换为您想要的值。
2. 用您的新组件[替换默认搜索对话框](#replace-search-dialog)。

171
content/blog/theme.mdx Normal file
View File

@ -0,0 +1,171 @@
---
title: Themes
description: Add Theme to Fumadocs UI
image: /images/blog/post-7.png
date: 2025-01-15T12:00:00.000Z
published: true
categories: [product, news]
author: mkdirs
---
## Usage
Note only Tailwind CSS v4 is supported:
```css title="Tailwind CSS"
@import 'tailwindcss';
@import 'fumadocs-ui/css/neutral.css';
@import 'fumadocs-ui/css/preset.css';
/* path of `fumadocs-ui` relative to the CSS file */
@source '../node_modules/fumadocs-ui/dist/**/*.js';
```
### Preflight Changes
By using the Tailwind CSS plugin, or the pre-built stylesheet, your default border, text and background
colors will be changed.
### Light/Dark Modes
Fumadocs supports light/dark modes with [`next-themes`](https://github.com/pacocoursey/next-themes), it is included in Root Provider.
See [Root Provider](/docs/layouts/root-provider#theme-provider) to learn more.
### RTL Layout
RTL (Right-to-left) layout is supported.
To enable RTL, set the `dir` prop to `rtl` in body and root provider (required for Radix UI).
```tsx
import { RootProvider } from 'fumadocs-ui/provider';
import type { ReactNode } from 'react';
export default function RootLayout({ children }: { children: ReactNode }) {
return (
<html lang="en" suppressHydrationWarning>
<body dir="rtl">
<RootProvider dir="rtl">{children}</RootProvider>
</body>
</html>
);
}
```
### Prefix
Fumadocs UI has its own colors, animations, and utilities.
By default, it adds a `fd-` prefix to avoid conflicts with Shadcn UI or your own CSS variables.
You can use them without the prefix by adding some aliases:
```css title="Tailwind CSS"
@theme {
--color-primary: var(--color-fd-primary);
}
```
> You can use it with CSS media queries for responsive design.
### Layout Width
Customise the max width of docs layout with CSS Variables.
```css
:root {
--fd-layout-width: 1400px;
}
```
{/* <WidthTrigger /> */}
## Tailwind CSS Preset
The Tailwind CSS preset introduces new colors and extra utilities including `fd-steps`.
### Themes
It comes with many themes out-of-the-box, you can pick one you prefer.
```css
@import 'fumadocs-ui/css/<theme>.css';
/* Example */
@import 'fumadocs-ui/css/black.css';
```
<Tabs items={['neutral', 'black', 'vitepress', 'dusk', 'catppuccin', 'ocean', 'purple']}>
<Tab value='neutral'>
![Neutral](/images/docs/themes/neutral.png)
</Tab>
<Tab value='black'>
![Black](/images/docs/themes/black.png)
</Tab>
<Tab value='vitepress'>
![Vitepress](/images/docs/themes/vitepress.png)
</Tab>
<Tab value='dusk'>
![Dusk](/images/docs/themes/dusk.png)
</Tab>
<Tab value='Catppuccin'>
![Catppuccin](/images/docs/themes/catppuccin.png)
</Tab>
<Tab value='ocean'>
![Ocean](/images/docs/themes/ocean.png)
</Tab>
<Tab value='purple'>
![Purple](/images/docs/themes/purple.png)
</Tab>
</Tabs>
### Colors
The design system was inspired by [Shadcn UI](https://ui.shadcn.com), you can easily customize the colors using CSS variables.
```css title="global.css"
:root {
--color-fd-background: hsl(0, 0%, 100%);
}
.dark {
--color-fd-background: hsl(0, 0%, 0%);
}
```
### Typography
We have a built-in plugin forked from [Tailwind CSS Typography](https://tailwindcss.com/docs/typography-plugin).
The plugin adds a `prose` class and variants to customise it.
```tsx
<div className="prose">
<h1>Good Heading</h1>
</div>
```
> The plugin works with and only with Fumadocs UI's MDX components, it may conflict with `@tailwindcss/typography`.
> If you need to use `@tailwindcss/typography` over the default plugin, [set a class name option](https://github.com/tailwindlabs/tailwindcss-typography/blob/main/README.md#changing-the-default-class-name) to avoid conflicts.

170
content/blog/theme.zh.mdx Normal file
View File

@ -0,0 +1,170 @@
---
title: 主题
description: 为 Fumadocs UI 添加主题
image: /images/blog/post-7.png
date: 2025-01-15T12:00:00.000Z
published: true
categories: [product, news]
author: mkdirs
---
## 使用方法
注意只支持 Tailwind CSS v4
```css title="Tailwind CSS"
@import 'tailwindcss';
@import 'fumadocs-ui/css/neutral.css';
@import 'fumadocs-ui/css/preset.css';
/* path of `fumadocs-ui` relative to the CSS file */
@source '../node_modules/fumadocs-ui/dist/**/*.js';
```
### 预设更改
通过使用 Tailwind CSS 插件或预构建的样式表,您的默认边框、文本和背景颜色将被更改。
### 明/暗模式
Fumadocs 通过 [`next-themes`](https://github.com/pacocoursey/next-themes) 支持明/暗模式,它包含在 Root Provider 中。
参见 [Root Provider](/docs/layouts/root-provider#theme-provider) 了解更多信息。
### RTL 布局
支持 RTL从右到左布局。
要启用 RTL请在 body 和 root providerRadix UI 需要)中将 `dir` 属性设置为 `rtl`。
```tsx
import { RootProvider } from 'fumadocs-ui/provider';
import type { ReactNode } from 'react';
export default function RootLayout({ children }: { children: ReactNode }) {
return (
<html lang="en" suppressHydrationWarning>
<body dir="rtl">
<RootProvider dir="rtl">{children}</RootProvider>
</body>
</html>
);
}
```
### 前缀
Fumadocs UI 有自己的颜色、动画和工具。
默认情况下,它添加了 `fd-` 前缀,以避免与 Shadcn UI 或您自己的 CSS 变量冲突。
您可以通过添加一些别名来使用它们,而无需前缀:
```css title="Tailwind CSS"
@theme {
--color-primary: var(--color-fd-primary);
}
```
> 您可以将其与 CSS 媒体查询一起使用,实现响应式设计。
### 布局宽度
使用 CSS 变量自定义文档布局的最大宽度。
```css
:root {
--fd-layout-width: 1400px;
}
```
{/* <WidthTrigger /> */}
## Tailwind CSS 预设
Tailwind CSS 预设引入了新的颜色和额外的工具,包括 `fd-steps`。
### 主题
它开箱即用地提供了许多主题,您可以选择一个您喜欢的。
```css
@import 'fumadocs-ui/css/<theme>.css';
/* Example */
@import 'fumadocs-ui/css/black.css';
```
<Tabs items={['neutral', 'black', 'vitepress', 'dusk', 'catppuccin', 'ocean', 'purple']}>
<Tab value='neutral'>
![Neutral](/images/docs/themes/neutral.png)
</Tab>
<Tab value='black'>
![Black](/images/docs/themes/black.png)
</Tab>
<Tab value='vitepress'>
![Vitepress](/images/docs/themes/vitepress.png)
</Tab>
<Tab value='dusk'>
![Dusk](/images/docs/themes/dusk.png)
</Tab>
<Tab value='Catppuccin'>
![Catppuccin](/images/docs/themes/catppuccin.png)
</Tab>
<Tab value='ocean'>
![Ocean](/images/docs/themes/ocean.png)
</Tab>
<Tab value='purple'>
![Purple](/images/docs/themes/purple.png)
</Tab>
</Tabs>
### 颜色
设计系统的灵感来自 [Shadcn UI](https://ui.shadcn.com),您可以使用 CSS 变量轻松自定义颜色。
```css title="global.css"
:root {
--color-fd-background: hsl(0, 0%, 100%);
}
.dark {
--color-fd-background: hsl(0, 0%, 0%);
}
```
### 排版
我们有一个内置插件,它是从 [Tailwind CSS Typography](https://tailwindcss.com/docs/typography-plugin) 派生而来的。
该插件添加了一个 `prose` 类和变体来自定义它。
```tsx
<div className="prose">
<h1>Good Heading</h1>
</div>
```
> 该插件仅与 Fumadocs UI 的 MDX 组件一起工作,它可能与 `@tailwindcss/typography` 冲突。
> 如果您需要使用 `@tailwindcss/typography` 而不是默认插件,请[设置类名选项](https://github.com/tailwindlabs/tailwindcss-typography/blob/main/README.md#changing-the-default-class-name)以避免冲突。

View File

@ -0,0 +1,62 @@
---
title: What is Fumadocs
description: Introducing Fumadocs, a docs framework that you can break.
image: /images/blog/post-1.png
date: 2025-04-01T12:00:00.000Z
published: true
categories: [company, product]
author: fox
---
Fumadocs was created because I wanted a more customisable experience for building docs, to be a docs framework that is not opinionated, **a "framework" that you can break**.
## Philosophy
**Less Abstraction:** Fumadocs expects you to write code and cooperate with the rest of your software.
While most frameworks are configured with a configuration file, they usually lack flexibility when you hope to tune its details.
You cant control how they render the page nor the internal logic. Fumadocs shows you how the app works, instead of a single configuration file.
**Next.js Fundamentals:** It gives you the utilities and a good-looking UI.
You are still using features of Next.js App Router, like **Static Site Generation**. There is nothing new for Next.js developers, so you can use it with confidence.
**Opinionated on UI:** The only thing Fumadocs UI (the default theme) offers is **User Interface**. The UI is opinionated for bringing better mobile responsiveness and user experience.
Instead, we use a much more flexible approach inspired by Shadcn UI — [Fumadocs CLI](/docs/cli), so we can iterate our design quick, and welcome for more feedback about the UI.
## Why Fumadocs
Fumadocs is designed with flexibility in mind.
You can use `fumadocs-core` as a headless UI library and bring your own styles.
Fumadocs MDX is also a useful library to handle MDX content in Next.js. It also includes:
- Many built-in components.
- Typescript Twoslash, OpenAPI, and Math (KaTeX) integrations.
- Fast and optimized by default, natively built on App Router.
- Tight integration with Next.js, you can add it to an existing Next.js project easily.
You can read [Comparisons](/docs/comparisons) if you're interested.
### Documentation
Fumadocs focuses on **authoring experience**, it provides a beautiful theme and many docs automation tools.
It helps you to iterate your codebase faster while never leaving your docs behind.
You can take this site as an example of docs site built with Fumadocs.
### Blog sites
Since Next.js is already a powerful framework, most features can be implemented with **just Next.js**.
Fumadocs provides additional tooling for Next.js, including syntax highlighting, document search, and a default theme (Fumadocs UI).
It helps you to avoid reinventing the wheels.
## When to use Fumadocs
For most of the web applications, vanilla React.js is no longer enough.
Nowadays, we also wish to have a blog, a showcase page, a FAQ page, etc. With a
fancy UI that's breathtaking, in these cases, Fumadocs can help you build the
docs easier, with less boilerplate.
Fumadocs is maintained by Fuma and many contributors, with care on the maintainability of codebase.
While we don't aim to offer every functionality people wanted, we're more focused on making basic features perfect and well-maintained.
You can also help Fumadocs to be more useful by contributing!

View File

@ -0,0 +1,60 @@
---
title: 什么是 Fumadocs
description: 介绍 Fumadocs一个可以打破常规的文档框架
image: /images/blog/post-1.png
date: 2025-04-01T12:00:00.000Z
published: true
categories: [company, product]
author: fox
---
Fumadocs 的创建是因为我想要一种更加可定制化的文档构建体验,一个不固执己见的文档框架,**一个你可以"打破"的"框架"**。
## 理念
**更少的抽象:** Fumadocs 期望您编写代码并与您的其余软件协作。
虽然大多数框架都是通过配置文件进行配置,但当您希望调整其细节时,它们通常缺乏灵活性。
您无法控制它们如何渲染页面或内部逻辑。Fumadocs 向您展示应用程序如何工作,而不是仅提供单一的配置文件。
**Next.js 基础:** 它为您提供实用工具和美观的 UI。
您仍然使用 Next.js App Router 的功能,如**静态站点生成**。对于 Next.js 开发者来说没有新的东西,所以您可以放心使用。
**对 UI 有自己的看法:** Fumadocs UI默认主题提供的唯一东西是**用户界面**。UI 的设计理念是提供更好的移动响应性和用户体验。
相反,我们使用受 Shadcn UI 启发的更灵活的方法 — [Fumadocs CLI](/docs/cli),这样我们可以快速迭代设计,并欢迎更多关于 UI 的反馈。
## 为什么选择 Fumadocs
Fumadocs 的设计考虑了灵活性。
您可以将 `fumadocs-core` 用作无头 UI 库并带来您自己的样式。
Fumadocs MDX 也是处理 Next.js 中 MDX 内容的有用库。它还包括:
- 许多内置组件。
- Typescript Twoslash、OpenAPI 和 Math (KaTeX) 集成。
- 默认情况下快速且优化,原生构建在 App Router 上。
- 与 Next.js 紧密集成,您可以轻松将其添加到现有的 Next.js 项目中。
如果您感兴趣,可以阅读 [比较](/docs/comparisons)。
### 文档
Fumadocs 专注于**创作体验**,它提供了一个漂亮的主题和许多文档自动化工具。
它帮助您更快地迭代代码库,同时不会落下您的文档。
您可以将此站点作为使用 Fumadocs 构建的文档站点的示例。
### 博客站点
由于 Next.js 已经是一个强大的框架,大多数功能可以**仅使用 Next.js** 实现。
Fumadocs 为 Next.js 提供了额外的工具包括语法高亮、文档搜索和默认主题Fumadocs UI
它帮助您避免重新发明轮子。
## 何时使用 Fumadocs
对于大多数 Web 应用程序,原生 React.js 已经不够用了。
如今我们还希望有一个博客、展示页面、FAQ 页面等。带有令人惊叹的精美 UI在这些情况下Fumadocs 可以帮助您更轻松地构建文档,减少样板代码。
Fumadocs 由 Fuma 和许多贡献者维护,关注代码库的可维护性。
虽然我们不打算提供人们想要的每一项功能,但我们更专注于使基本功能完美且维护良好。
您也可以通过贡献来帮助 Fumadocs 变得更加有用!