Onlook 文档站工程解析:基于 Fumadocs 与 Next.js 的文档站点结构、运行与扩展指南
【免费下载链接】onlookThe Cursor for Designers • An Open-Source AI-First Design tool • Visually build, style, and edit your React App with AI项目地址: https://gitcode.com/GitHub_Trending/on/onlook
本篇技术指南以docs/目录为对象,系统讲解 Onlook 开源项目官方文档站的工程实现:它基于 Next.js 与 Fumadocs 构建,包含内容源适配、MDX 集合、全站搜索与静态站点生成等完整链路。读完本文,你将掌握该文档站从本地运行、目录组织、路由映射到构建部署的完整脉络,并能在现有分区结构上平滑扩展新文档。
文档站概览:一个由 Fumadocs 驱动的 Next.js 应用
docs/README.md明确指出,docs/是Onlook 官方文档的一个 Next.js 应用程序("This is a Next.js application for the Onlook documentation")。结合 docs/package.json 可以确认其完整技术栈:
| 依赖 | 版本(以仓库为准) | 作用 |
|---|---|---|
next | 16.0.7 | 应用框架与静态站点生成 |
react/react-dom | 19.2.0 | UI 运行时 |
fumadocs-core | 16.0.2 | 内容源加载与页面树构建 |
fumadocs-mdx | 13.0.0 | MDX 集合与 frontmatter 校验 |
fumadocs-ui | 16.0.2 | 文档布局、页面、目录(TOC)等 UI 组件 |
next-sitemap | 4.2.3 | 构建期生成 sitemap |
tailwindcss/@tailwindcss/postcss | 4.1.5 | 样式系统 |
@onlook/ui | *(monorepo 内部包) | 复用仓库统一 UI 组件(如按钮、图标) |
该文档站与 Onlook 主产品共享同一个 monorepo,通过@onlook/ui、@onlook/eslint等内部包保持设计与工程规范的一致性,这也是理解其代码组织的关键前提。
本地运行:启动开发服务器
README 给出的三种启动方式在 docs/package.json 的scripts中均有对应实现:
bun run dev # 或 pnpm dev # 或 yarn dev启动后使用浏览器打开http://localhost:3000即可查看文档站。几个值得注意的实现细节:
dev脚本实际是next dev --turbo,即使用 Next.js 的 Turbopack 作为开发打包器(docs/package.json)。postinstall钩子会执行fumadocs-mdx:这是 Fumadocs MDX 的命令行工具,负责扫描content/目录并生成内容源文件(即@/.source模块),因此在安装依赖后首次构建/开发前,这一步骤会自动完成。- 环境校验可跳过:在 docs/next.config.ts 的头部注释中说明,执行
build或dev时可通过设置SKIP_ENV_VALIDATION跳过环境变量校验,这在 Docker 构建等场景下尤其有用。 - 开发期依赖外部根目录:同一文件中可见,当
NODE_ENV === 'development'时,nextConfig.outputFileTracingRoot被指向 monorepo 根目录(path.join(__dirname, '../../..')),确保 monorepo 内部包依赖在开发模式下能被正确追踪。
next.config.ts 的核心逻辑是用createMDX()(来自fumadocs-mdx/next)包装 Next 配置,并开启reactStrictMode: true,使 MDX 内容可以无缝参与 Next.js 的编译流程。
目录结构与路由总览
README 的 "Explore" 一节给出了文档站的关键入口文件与路由分工,下面结合仓库实际代码逐一展开。
内容源适配器:lib/source.ts
lib/source.ts 是整个文档站的数据入口,它只做了两件事:
import { docs } from '@/.source'; import { loader } from 'fumadocs-core/source'; export const source = loader({ baseUrl: '/', source: docs.toFumadocsSource(), });docs来自@/.source,这个模块正是postinstall阶段由fumadocs-mdx根据content/目录自动生成的;loader()是 Fumadocs 的内容加载器,baseUrl: '/'决定页面 URL 的挂载根路径,docs.toFumadocsSource()把 MDX 集合转换为 Fumadocs 可消费的源对象;- 导出的
source对象被页面渲染、路由处理、搜索接口等多处复用,是全站内容的单一事实来源。
共享布局配置:app/layout.config.tsx
layout.config.tsx 导出baseOptions: BaseLayoutProps,作为所有布局共享的选项:
nav.title:导航栏标题,由@onlook/ui/icons的Icons.OnlookLogo图标 + "Onlook Docs" 文本组成;links:导航右侧的两个外链入口(GitHub 仓库与 Discord 社区),均以type: 'main'主链接形式呈现,并带有对应图标。
文件中还注明:Home 与 Docs 两个布局分别由app/(home)/layout.tsx与app/docs/layout.tsx定义,可从baseOptions出发按需定制。
路由表与真实目录映射
README 的路由表描述的是通用 Fumadocs 脚手架结构,在 Onlook 仓库中实际落点如下:
| README 中的路由 | 说明 | 本仓库中的对应实现 |
|---|---|---|
app/(home) | 着陆页及其余页面 | 对应 docs/src/app/[[...slug]]/page.tsx(根路径index.mdx渲染) |
app/docs | 文档布局与页面 | 由 docs/src/app/layout.tsx 的DocsLayout+ content/docs 的 MDX 内容共同构成 |
app/api/search/route.ts | 搜索的 Route Handler | 对应 docs/src/app/api/search/route.ts |
从源码结构看,README 描述的通用脚手架在 Onlook 中被收敛为「一个捕获全部 slug 的页面 + 一个文档布局 + 一个搜索接口」的最小形态。
文档内容结构:MDX 集合与分区组织
内容源定义:source.config.ts
source.config.ts 定义了文档内容的两类集合 schema:
export const docs = defineDocs({ docs: { schema: frontmatterSchema, }, meta: { schema: metaSchema, }, }); export default defineConfig({ mdxOptions: { // MDX options }, });defineDocs注册docs(正文 MDX 页面)与meta(目录元信息meta.json)两种集合;frontmatterSchema/metaSchema来自fumadocs-mdx/config,可在 Zod schema 层面自定义 frontmatter 字段;- 注释指向 Fumadocs 官方 "collections" 文档,说明这是 Fumadocs MDX 的标准扩展点。
内容分区(Documentation Structure)
README 列出的分区在仓库中有完整落盘,实际目录为 content/docs,每个子目录均配有meta.json控制侧边栏顺序:
| 分区 | README 描述 | 仓库内容 |
|---|---|---|
| Getting Started | 快速上手与安装指南 | getting-started:core-features、ui-overview、first-project |
| User Guide | 综合使用指南 | 与 Getting Started 内容合并体现 |
| Features | 功能详解 | 分散在各分区(如core-features) |
| Tutorials | 分步操作教程 | tutorials:figma-to-onlook、importing-templates |
| Developer Documentation | 面向贡献者的技术文档 | developers:architecture、running-locally、troubleshooting、appendix |
| 其他 | — | self-hosting(docker-compose、oauth-setup、cloud-deployment 等)、migrations、faq.mdx、enterprise.mdx |
每个分区的meta.json(如 docs/content/docs/meta.json)通过pages数组声明该层级的页面与子目录顺序,Fumadocs 据此生成侧边栏与面包屑。
MDX 页面示例
以 docs/content/docs/index.mdx 为典型样例,可以看到文档页的标准写法:
- frontmatter:
title与description会被 page.tsx 的generateMetadata读取,用于生成页面标题、描述与社交分享信息; <Cards>/<Card>组件:由 docs/src/mdx-components.tsx 注入,用于渲染入口卡片;- 图片与 iframe:可内嵌站点图片与视频,正文使用标准 Markdown。
页面渲染、搜索与布局的源码实现
页面渲染:[[...slug]]/page.tsx
docs/src/app/[[...slug]]/page.tsx 是文档站的渲染核心,其关键行为包括:
source.getPage(params.slug)按路由参数查找内容页,查不到则notFound();- 通过
createRelativeLink(source, page)(来自fumadocs-ui/mdx)支持在 MDX 内以相对文件路径互相链接; generateStaticParams()返回source.generateParams(),使所有文档页在构建期被静态化输出;generateMetadata()为每个页面生成标题、描述,并自动计算 OG 图片 URL(/docs-og/.../image.png路径规则),同时填充 Open Graph 与 Twitter Card 元数据;- 页面底部渲染
EditGitHub组件(edit-gh.tsx),它根据当前 slug 拼出源文件路径,提供"Edit on GitHub"跳转,方便读者直接修改对应 MDX 文档。
搜索:api/search/route.ts
docs/src/app/api/search/route.ts 全文件只有三行:
import { source } from '@/lib/source'; import { createFromSource } from 'fumadocs-core/search/server'; export const { GET } = createFromSource(source);createFromSource基于已加载的source直接生成搜索 API(Route Handler),无需额外配置索引数据库,这也解释了为什么 README 将搜索路由列为"开箱即用"的能力。
全局布局:layout.tsx
docs/src/app/layout.tsx 负责组装整站外壳:
- 引入 Geist 字体(
next/font/google)并注入 CSS 变量; - 使用
DocsLayout tree={source.pageTree}渲染带侧边栏的文档布局,RootProvider提供主题等全局能力; metadata定义站名(Onlook Docs)、描述("Open-source Cursor for Designers...")、robots: index/follow等 SEO 元信息;- 仅在生产环境(
NODE_ENV === 'production')注入分析脚本(Zaraz)与RB2BLoader(rb2b-loader.tsx),避免开发期受第三方脚本干扰。
构建、部署与 SEO 配套
README 虽然只讲了dev,但仓库为生产构建提供了完整脚本(docs/package.json):
build:next build(支持SKIP_ENV_VALIDATION跳过校验,适合 Docker 构建);start:next start以生产模式运行;postbuild:next-sitemap,构建完成后自动生成站点地图;typecheck:tsc --noEmit做类型检查;lint/format由 ESLint 承担。
sitemap 配置见 next-sitemap.config.js:siteUrl指向https://docs.onlook.dev,generateRobotsTxt: false且注释说明 robots 由独立 Route Handler 处理(对应 docs/src/app/robots.txt/route.ts),并开启generateIndexSitemap。构建产物中 docs/public/sitemap.xml 与sitemap-0.xml即为该机制的实际输出,可作为验证。
扩展文档站的实战建议
基于以上源码结构,若要为 Onlook 文档站新增内容,标准流程是:
- 在 content/docs 对应分区(或新建分区目录)添加
.mdx文件,并在同目录meta.json的pages数组登记顺序; - 在 frontmatter 中填写
title与description(它们会同时驱动标题、SEO 与搜索); - 需要新入口卡片时,参考 index.mdx 中
<Cards>/<Card>的用法; - 重启
dev或重新构建——fumadocs-mdx会在postinstall/构建阶段自动重新生成@/.source,新页面即可通过http://localhost:3000访问,并自动纳入侧边栏、搜索与 sitemap。
README 末尾的 "Learn More" 指向 Next.js 官方文档与交互式教程,意在提示开发者文档站底层完全基于 Next.js 生态,掌握 App Router、next dev --turbo、静态生成(SSG)与 Route Handler 等概念,将有助于深度定制该文档站。整体而言,docs/是一个小而完整的 Fumadocs + Next.js 文档工程样例:内容与渲染解耦、搜索零配置、SEO 与站点地图自动生成,非常适合作为自建技术文档站的参考模板。
【免费下载链接】onlookThe Cursor for Designers • An Open-Source AI-First Design tool • Visually build, style, and edit your React App with AI项目地址: https://gitcode.com/GitHub_Trending/on/onlook
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考