
# API 参考

`onedocs` 软件包的所有导出内容完整参考。

## 入口点

| 导入 | 描述 |
|--------|-------------|
| `onedocs` | 主入口 - 布局、组件、`mdxComponents`、`defineConfig`、源码辅助工具 |
| `onedocs/components` | Fumadocs UI 组件，以及 `InstallBlock`、`CodeBlock`、`Button` 和 `Logo` |
| `onedocs/config` | 配置辅助工具 |
| `onedocs/source` | 内容源实用工具 |
| `onedocs/metadata` | 元数据生成 |
| `onedocs/og` | OpenGraph 图片生成 |
| `onedocs/llms` | LLMs.txt 生成 |
| `onedocs/seo` | 站点地图和 robots.txt |
| `onedocs/css/preset.css` | Tailwind CSS 预设 |

## 布局

### DocsLayout

文档页面的主布局包装器。提供侧边栏导航、搜索和主题切换功能。

```tsx
import { DocsLayout } from "onedocs";

export default function Layout({ children }: { children: React.ReactNode }) {
  return (
    <DocsLayout config={config} pageTree={source.pageTree}>
      {children}
    </DocsLayout>
  );
}
```

**属性：**
- `config` - 你的 `OnedocsConfig` 对象
- `pageTree` - 来自源的页面树（例如 e.g、`source.pageTree`）
- `children` - 页面内容

### DocsPage

单个文档页面的包装器。它会包装 Fumadocs UI `DocsPage`，并将内容放入 `DocsBody`。

```tsx
import { DocsPage, mdxComponents } from "onedocs";
import { notFound } from "next/navigation";

export default async function Page(props: {
  params: Promise<{ slug?: string[] }>;
}) {
  const params = await props.params;
  const page = source.getPage(params.slug);
  if (!page) notFound();
  const MDX = page.data.body;

  return (
    <DocsPage toc={page.data.toc}>
      <MDX components={mdxComponents} />
    </DocsPage>
  );
}
```

**属性：**
- `toc` - 来自页面数据的目录
- `children` - MDX 内容
- Fumadocs UI `DocsPage` 的任何其他属性，例如 `full`

### DocsBody

文档内容的内部正文包装器。由 `DocsPage` 在内部使用。

```tsx
import { DocsBody } from "onedocs";

<DocsBody>
  <MDX components={mdxComponents} />
</DocsBody>
```

### HomePage

包含主视觉区、功能介绍和页脚的完整落地页组件。

```tsx
import { HomePage, CTASection } from "onedocs";

export default function Home() {
  return (
    <HomePage config={config} packageName="my-package">
      <CTASection
        title="Ready to get started?"
        cta={{ label: "Read the Docs", href: "/docs" }}
      />
    </HomePage>
  );
}
```

**属性：**
- `config` - 你的 `OnedocsConfig` 对象
- `packageName` - 安装代码块使用的软件包名称（可选）
- `children` - 功能介绍与页脚之间的内容（可选）

查看[主页](https://onedocs.inline0.dev/zh/docs/configuration#homepage)和[页脚](https://onedocs.inline0.dev/zh/docs/configuration#footer)，了解配置的控制内容。

### HomeLayout

主页的基础布局（由 `HomePage` 在内部使用）。

```tsx
import { HomeLayout } from "onedocs";

<HomeLayout config={config}>
  {/* Custom homepage content */}
</HomeLayout>
```

### createBaseOptions

根据你的配置生成 Fumadocs UI 布局选项（导航栏标题或徽标、`nav.links` 和 GitHub 链接）。`DocsLayout` 和 `HomeLayout` 会使用它；直接渲染 Fumadocs UI 布局时，请自行调用。

```tsx
import { DocsLayout } from "fumadocs-ui/layouts/docs";
import { createBaseOptions } from "onedocs";

<DocsLayout {...createBaseOptions(config)} tree={source.pageTree}>
  {children}
</DocsLayout>
```

## 组件

### InstallBlock

显示用于安装 npm、yarn、pnpm 和 bun 的包管理器选项卡（`npm i`、`yarn add`、`pnpm add`、`bun add`）。这是一个异步服务器组件。

```tsx
import { InstallBlock } from "onedocs";

<InstallBlock packageName="onedocs" />
```

**属性：**
- `packageName` - 要安装的 npm 包名称
- `title` - 选项卡上方的标题（可选）
- `description` - 选项卡上方的文本（可选）
- `children` - 选项卡下方的内容（可选）

### Button

圆角链接，样式为主按钮。只有一种样式。

```tsx
import { Button } from "onedocs";

<Button href="/docs">Get Started</Button>
```

**属性：**
- `href` - 链接目标
- `children` - 按钮文本
- `className` - 额外类名（可选）

### Logo

同时渲染浅色和深色图片，并显示与当前主题匹配的图片。`DocsLayout` 和 `HomePage` 会将它用于带有浅色和深色变体的 `logo`。

```tsx
import { Logo } from "onedocs";

<Logo light="/logo-light.svg" dark="/logo-dark.svg" alt="My Project" className="h-6" />
```

**属性：**
- `light` - 浅色模式图片路径
- `dark` - 深色模式图片路径
- `alt` - 替代文本（默认值：`"Logo"`）
- `className` - 两张图片共用的类名（可选）

### CTASection

主页的行动号召区域。

```tsx
import { CTASection } from "onedocs";

<CTASection
  title="Ready to get started?"
  description="Optional description text"
  cta={{ label: "Get Started", href: "/docs" }}
/>
```

**属性：**
- `title` - 区域标题
- `description` - 标题下方的文本（可选）
- `cta` - 按钮配置，包含 `label` 和 `href`
- `children` - 按钮下方的内容（可选）

### FontHead

预加载 Inter Variable 字体，声明其 `@font-face`，并将其设为页面字体。将其添加到根布局的 `<head>` 中。

```tsx
import { FontHead } from "onedocs";

<html>
  <head>
    <FontHead />
  </head>
  <body>{children}</body>
</html>
```

Onedocs 不会附带该字体。默认情况下，`FontHead` 会加载 `/fonts/InterVariable.woff2`，因此请将文件放入 `public/fonts/`，或传入另一个带有 `fontPath` 的 URL：

```tsx
<FontHead fontPath="/assets/Inter.woff2" />
```

### GitHubIcon

GitHub 图标组件（内部用于导航）。

```tsx
import { GitHubIcon } from "onedocs";

<GitHubIcon className="size-5" />
```

### CodeBlock

语法高亮代码块，在服务器上通过 Shiki 和 Fumadocs 进行高亮。这是一个异步服务器组件。

```tsx
import { CodeBlock } from "onedocs";

<CodeBlock lang="tsx" code="const x = 1;" />
```

## 配置

### defineConfig

类型安全的配置辅助函数。

```tsx
import { defineConfig } from "onedocs/config";

export default defineConfig({
  title: "My Docs",
  // ... other options
});
```

### OnedocsConfig

用于配置的 TypeScript 类型。

```tsx
import type { OnedocsConfig } from "onedocs/config";

const config: OnedocsConfig = {
  title: "My Docs",
};
```

所有选项请参阅 [配置](https://onedocs.inline0.dev/zh/docs/configuration)。

## 源工具函数

### loader

重新导出 `fumadocs-core/source` 加载器，用于创建内容源。

```tsx
import { loader } from "onedocs/source";

export const source = loader({
  baseUrl: "/docs",
  source: docs.toFumadocsSource(),
});
```

### createSource

用于创建内容源的辅助函数（加载器的封装）。基础 URL 默认为 `/docs`。

```tsx
import { createSource } from "onedocs/source";
import { docs } from "../../.source/server";

export const source = createSource(docs);
// export const source = createSource(docs, { baseUrl: "/guide" });
```

在 0.1.27 中，`createSource` 会返回未指定类型的源，因此读取 `page.data` 时，TypeScript 会报告诸如 `Property 'data' does not exist on type 'unknown'` 之类的错误（[问题 #4](https://github.com/inline0/onedocs/issues/4)）。修复之前，请按上文所示使用 `loader`。

## 元数据

### createMetadata

为根布局生成 Next.js 元数据。

```tsx
import { createMetadata } from "onedocs/metadata";

export const metadata = createMetadata(config, {
  baseUrl: "https://example.com",
});
```

**选项：**
- `baseUrl` - 网站的基础 URL（可选）
- `additional` - 额外的 `Metadata` 字段，在最后合并（可选）

**返回：** Next.js `Metadata` 对象，包含：
- 标题（`config.title`）和标题模板（`%s | Site Name`）
- 描述
- 设置 `config.icon` 时提供的站点图标
- 设置 `baseUrl` 时：`metadataBase`、OpenGraph 元数据和 Twitter `summary_large_image` 卡片

### createDocsPageMetadata

为文档页面生成标题和描述元数据。它接收一个包含 `title` 和可选 `description` 的对象。

```tsx
import { createDocsPageMetadata } from "onedocs/metadata";
import { notFound } from "next/navigation";

export async function generateMetadata(props: {
  params: Promise<{ slug?: string[] }>;
}) {
  const params = await props.params;
  const page = source.getPage(params.slug);
  if (!page) notFound();

  return createDocsPageMetadata({
    title: page.data.title,
    description: page.data.description,
  });
}
```

如需为每个页面设置 Open Graph 图片，请参阅 [动态 OG 图片](#dynamic-og-images)。

## OpenGraph 图片

### createRootOGImage

为主页创建 OG 图片：徽标居中显示在黑色背景上。

```tsx
// src/app/opengraph-image.tsx
import {
  createRootOGImage,
  loadPublicFile,
  ogImageSize,
  ogImageContentType,
  type OGImageLogo,
} from "onedocs/og";

export const size = ogImageSize;
export const contentType = ogImageContentType;

export default async function Image() {
  const logo = await loadPublicFile("logo-dark.svg");
  return createRootOGImage(logo as OGImageLogo);
}
```

### createDocsOGImage

为文档页面创建 OG 图片：徽标位于左上角，标题以白色显示在黑色背景上。字体参数为可选；若未提供，标题将使用系统字体。

```tsx
// src/app/docs/opengraph-image.tsx
import {
  createDocsOGImage,
  loadPublicFile,
  loadInterFont,
  ogImageSize,
  ogImageContentType,
  type OGImageLogo,
} from "onedocs/og";

export const size = ogImageSize;
export const contentType = ogImageContentType;

export default async function Image() {
  const [logo, font] = await Promise.all([
    loadPublicFile("logo-dark.svg"),
    loadInterFont(),
  ]);
  return createDocsOGImage("Documentation", logo as OGImageLogo, font);
}
```

### 动态 OG 图片

如需为每个页面设置 OG 图片，请通过路由提供图片。页面不会自动指向此路由：请自行将其添加到每个页面的元数据中，例如与 `createDocsPageMetadata` 中的字段一起添加 `openGraph: { images: "/docs/og/getting-started" }`。

```tsx
// src/app/docs/og/[...slug]/route.tsx
import {
  createDocsOGImage,
  loadPublicFile,
  loadInterFont,
  type OGImageLogo,
} from "onedocs/og";
import { source } from "@/lib/source";

export async function GET(
  _request: Request,
  { params }: { params: Promise<{ slug: string[] }> }
) {
  const { slug } = await params;
  const page = source.getPage(slug);
  const title = page?.data.title ?? "Documentation";

  const [logo, font] = await Promise.all([
    loadPublicFile("logo-dark.svg"),
    loadInterFont(),
  ]);

  return createDocsOGImage(title, logo as OGImageLogo, font);
}
```

### 辅助函数

| 函数 | 描述 |
|----------|-------------|
| `loadPublicFile(path)` | 从 `public/` 加载文件，作为数据 URL 和缓冲区；对于 SVG，还会读取 `width` 和 `height` 属性 |
| `loadInterFont(path?)` | 为 OG 图片从 `public/` 加载字体，默认使用 `fonts/Inter-Medium.ttf` |
| `ogImageSize` | 标准 OG 图片尺寸 `{ width: 1200, height: 630 }` |
| `ogImageContentType` | MIME 类型 `"image/png"` |

**必需文件：**
- `public/logo-dark.svg` - 用于 OG 图片的徽标。OG 辅助函数会根据其 `width` 和 `height` 属性调整尺寸，因此 `<svg>` 标签的这两个属性都必须是纯数字。
- `public/fonts/Inter-Medium.ttf` - 标题字体。Onedocs 不会附带该字体。

## LLMs.txt

为 AI 助手生成 LLMs.txt 文件。

### generateLLMsText

生成简洁的 LLMs.txt 内容。接收一个由 `createLLMsSource` 和 `{ title, description? }` 封装的源，并返回一个 promise。

```tsx
// src/app/llms.txt/route.ts
import { createLLMsSource, generateLLMsText } from "onedocs/llms";
import { source } from "@/lib/source";

export async function GET() {
  const content = await generateLLMsText(createLLMsSource(source), {
    title: "My Project",
    description: "Project description",
  });

  return new Response(content, {
    headers: { "Content-Type": "text/plain; charset=utf-8" },
  });
}
```

页面 URL 按源中的原样写入，例如 `/docs/getting-started`，不含域名。

### generateLLMsFullText

生成包含完整页面内容的完整 LLMs.txt。只接收封装后的源，并返回一个 promise。

```tsx
// src/app/llms-full.txt/route.ts
import { createLLMsSource, generateLLMsFullText } from "onedocs/llms";
import { source } from "@/lib/source";

export async function GET() {
  const content = await generateLLMsFullText(createLLMsSource(source));

  return new Response(content, {
    headers: { "Content-Type": "text/plain; charset=utf-8" },
  });
}
```

仅当 Fumadocs MDX 的 `includeProcessedMarkdown` 已启用时，才会包含页面正文；请参阅 [SEO 与搜索](https://onedocs.inline0.dev/zh/docs/seo-search#full-content-version)。

### createLLMsSource

将 Fumadocs 源（`loader()` 或 `createSource()` 结果）包装成上述两个函数所读取的结构：每个页面的 URL、标题、描述和文本加载器。

## SEO

### generateSitemap

为文档生成站点地图。接收一个对象：`baseUrl`、`pages` 列表（通常来自 `meta.json`）以及可选的 `docsPath`（默认值为 `/docs`）。

```tsx
// src/app/sitemap.ts
import { generateSitemap } from "onedocs/seo";
import meta from "../../content/docs/meta.json";

export default function sitemap() {
  return generateSitemap({
    baseUrl: "https://example.com",
    pages: meta.pages ?? [],
  });
}
```

如需了解条目如何变成 URL，请参阅 [SEO 与搜索](https://onedocs.inline0.dev/zh/docs/seo-search#sitemap)。

### generateRobots

生成 robots.txt 内容：允许所有内容，并额外包含 `Host` 和 `Sitemap` 行。`sitemapPath` 默认为 `/sitemap.xml`。

```tsx
// src/app/robots.ts
import { generateRobots } from "onedocs/seo";

export default function robots() {
  return generateRobots({
    baseUrl: "https://example.com",
  });
}
```

## CSS 预设

在你的 `globals.css` 中导入 CSS 预设：

```css
@import "onedocs/css/preset.css";

@source "./**/*.tsx";
@source "../../content/**/*.mdx";
```

`@source` 路径相对于 `src/app/globals.css`。

此预设包含：
- Tailwind CSS v4（请自行安装 `tailwindcss` 和 `@tailwindcss/postcss`）
- Fumadocs 中性色主题
- Fumadocs 预设样式
- 将 `--font-sans` 设置为 `FontHead` 定义的 `--font-inter` 变量
- 正文和标题的 Inter OpenType 特性
- 全高布局样式和 Onedocs 布局调整

## MDX 组件

`mdxComponents` 导出会展开 Fumadocs UI 默认 MDX 组件，并添加下列组件：

```tsx
import { mdxComponents } from "onedocs";

<MDX components={mdxComponents} />
```

**包含的组件：**
- Fumadocs UI 默认组件：`pre`（代码块）、`a`、`img`、从 `h1` 到 `h6`（带锚点的标题）、`table`、`CodeBlockTab`、`CodeBlockTabs`、`CodeBlockTabsList`、`CodeBlockTabsTrigger`、`CalloutContainer`、`CalloutTitle`、`CalloutDescription`
- `Callout` - 信息、警告和错误提示框
- `Card`、`Cards` - 卡片布局
- `Tab`、`Tabs` - 选项卡内容
- `Step`、`Steps` - 编号步骤
- `Accordion`、`Accordions` - 可折叠区域
- `File`、`Folder`、`Files` - 文件树
- `ImageZoom` - 可缩放图片
- `TypeTable` - 类型文档表格

不包含 `InstallBlock` 和 `CodeBlock`；请按照 [组件](https://onedocs.inline0.dev/zh/docs/components#more-components) 中的示例自行添加。

用法示例请参阅 [组件](https://onedocs.inline0.dev/zh/docs/components)。
