> ## Documentation Index
> Fetch the complete documentation index at: https://docs.vibestrap.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Fumadocs 内容集合（blog + changelog）

> Vibestrap 的 blog 和 changelog 用 Fumadocs MDX，与 Mintlify docs 站的分工。

Vibestrap 用了两套 MDX 系统，各司其职：

* **`/docs` 站**（你正在看的这个，`docs.vibestrap.dev`）跑在 **Mintlify** 上，
  内容在仓库根的 `docs/` 和 `docs/docs.json`。接入指南：
  [部署 docs 到 Mintlify](/zh/deployment/mintlify)。
* **营销应用上的 `/blog` 和 `/changelog`** 跑在
  **[Fumadocs](https://fumadocs.vercel.app/)** 上，MDX 在 `content/blog/` 和
  `content/changelog/`。本篇说的就是这两个。

分开是有意为之：docs 用 Mintlify 拿到现成的导航 / 搜索 / AI 助手 / 多语言；
blog 和 changelog 是营销站的一部分，跟 Next.js 应用同站更合理（共享主题、
共享分析、locale 路由统一）。

## 集合是如何定义的

`source.config.ts`：

```ts theme={null}
export const blog = defineCollections({
  type: 'doc',
  dir: 'content/blog',
  schema: frontmatterSchema.extend({ /* date, author, categories, … */ }),
});

export const changelog = defineCollections({
  type: 'doc',
  dir: 'content/changelog',
  schema: frontmatterSchema.extend({ version: z.string(), date: ... }),
});

export const pages = defineCollections({
  type: 'doc',
  dir: 'content/pages',
  schema: frontmatterSchema,
});
```

每条定义指定一个 `dir` 与 Zod schema。构建时会生成 `.source/server.ts`，
导出类型化的数组，由 `src/lib/source.ts` 消费。

## 新增一篇博客

Blog 的 frontmatter 字段最多：

```md theme={null}
---
title: 欢迎来到 Vibestrap
description: 一句话总结。
date: 2026-04-27
author: Vibestrap
categories: [release, indie-hacking]
---
```

把文件丢到 `content/blog/<slug>.mdx` 加上 `<slug>.zh.mdx`。
博客索引页用 `pickByLocale(blog, locale)` 读取，按 `date` 倒序——无需额外配置。

## 新增一条 changelog

跟 blog 一样的结构，多一个必填的 `version`：

```md theme={null}
---
title: v1.1 —— 积分包
description: 小但精。
version: 1.1.0
date: 2026-05-15
---
```

文件放到 `content/changelog/`。`version` 字段决定标题展示和 `/changelog` 上的排序。

## `pages` 集合

`content/pages/` 是杂项 MDX 页面的家——不属于 blog 或 changelog 的内容。
当前只有占位符。需要 MDX 渲染但不要侧边栏导航时用它。

## 自定义 MDX 组件

`src/mdx-components.tsx` 是 blog + changelog 渲染的统一覆盖点。它把样式
交给 Tailwind 的 `prose` 插件。在这里加自定义 shortcode：

```tsx theme={null}
export function getMDXComponents(components?: MDXComponents): MDXComponents {
  return {
    Callout: ({ children }) => <div className="callout">{children}</div>,
    ...components,
  };
}
```

之后任意 blog / changelog MDX 文件里就能用 `<Callout>...</Callout>` 了。
（Mintlify docs 站有它自己的组件库——见
[Mintlify Components](https://mintlify.com/docs/components)。）

## 验证生效

```bash theme={null}
pnpm exec fumadocs-mdx   # 重新生成 .source/
pnpm dev                 # 访问新文章
pnpm build               # frontmatter schema 错误会在这里暴露
```

`pnpm build` 会自动跑 `fumadocs-mdx`——frontmatter 不合规则时会以 Zod 错误
失败、明确指出文件。

## 常见坑

1. **忘记重新生成 `.source/`**——加文件后 dev 里 404，跑一下
   `pnpm exec fumadocs-mdx`。
2. **frontmatter 不合法**——Zod 拒绝未知字段。`date` 必须能解析、
   changelog 必须有 `version`、`published: false` 会隐藏博客。
3. **MDX autolink**——写 `<https://example.com>` 会让 MDX 解析炸。
   用 `[example.com](https://example.com)` 或裸 URL。
4. **目录搞错**——配置目录之外的文件会被静默忽略，对照 `source.config.ts`。
5. **不要把 docs 放这里**——任何想出现在 `/docs` 上的内容都属于仓库根的
   `docs/`（Mintlify），不是 `content/docs/`。

## 官方文档

* [fumadocs.vercel.app](https://fumadocs.vercel.app/) —— Fumadocs 参考
* [Fumadocs MDX](https://fumadocs.vercel.app/docs/mdx) —— 集合配置
* [MDX](https://mdxjs.com/) —— Markdown + JSX 语法
* [Zod](https://zod.dev/) —— frontmatter schema 语法
