基于 Create Fumadocs 构建 Next.js 静态导出的 Fumadocs MDX 文档站:从模板生成到部署
基于 Create Fumadocs 构建 Next.js 静态导出的 Fumadocs MDX 文档站从模板生成到部署【免费下载链接】fumadocsThe beautiful flexible React.js docs framework.项目地址: https://gitcode.com/GitHub_Trending/fu/fumadocs导读本文围绕packages/create-app/template/nextfuma-docs-mdxstatic/README.md这一模板说明文档展开完整讲解如何通过 Create Fumadocs 脚手架生成一个启用 Next.js Static Export静态导出的 Fumadocs MDX 文档站并深入剖析生成项目的目录结构、内容源加载、静态搜索、OG 图片与 LLM 文本导出等核心能力。读完本文你将掌握npm run dev本地开发、next build静态导出、serve out本地预览以及把产物部署到任意 CDN 的完整链路并理解lib/source.ts、lib/layout.shared.tsx、app/api/search/route.ts等关键文件背后的实现原理。1. 模板概览什么是nextfuma-docs-mdxstatic在 Create Fumadocs 脚手架中nextfuma-docs-mdxstatic是面向 Next.js 的模板之一与常规的nextfuma-docs-mdx模板相比它的核心区别在于生成的项目预先配置了 Next.js 的 Static Export静态导出模式。在 packages/create-app/src/constants.ts 中可以看到完整的模板注册表其中对两种 Next.js 模板的描述如下模板值标签说明nextfuma-docs-mdxNext.js: Fumadocs MDXrecommended: powerful and maturenextfuma-docs-mdxstaticNext.js Static: Fumadocs MDX静态导出模式无后端静态导出的含义是next build时会将整个站点渲染为一组纯 HTML、CSS、JS 与静态资源文件输出到out/目录因此可以托管在任何静态文件服务器或 CDN 上无需 Node.js 服务端、无需持续运行的进程。这非常适合文档站这类以内容为主、交互有限的场景。在 Create Fumadocs 的执行入口 packages/create-app/src/index.ts 中脚手架会按以下流程生成项目根据用户选择的template值查找对应的模板信息将template/value目录整体拷贝到输出目录其中example.gitignore会被重命名为.gitignore读取模板中的package.json把workspace:*形式的依赖替换为实际版本号并将包名改为项目目录名为生成的README.md追加# 项目名标题按选项执行依赖安装installDeps与 Git 仓库初始化initializeGit。也就是说本文所对应的README.md正是生成后的项目自带的说明文件它同时存在于 packages/create-app/template/nextfuma-docs-mdxstatic/README.md 模板目录中。2. 从零生成并启动项目模板说明中给出的启动方式如下npm run dev # or pnpm dev # or yarn dev打开 http://localhost:3000 即可在浏览器中看到结果。生成后的项目脚本定义参见 examples/next-static/package.json 中与之同构的示例项目脚本命令用途devnext dev启动开发服务器默认端口 3000buildnext build构建项目静态导出模式下产物输出到out/startserve out用静态服务器本地预览构建产物types:checknext typegen tsc --noEmit类型检查其中start使用serve包直接服务out/目录——这正是静态导出工作流的标志构建与运行彻底解耦本地npm run start与线上 CDN 的行为完全一致。dev阶段你依然拥有完整的 Next.js 开发体验热更新、快速刷新构建时则由 examples/next-static/next.config.mjs 中的配置接管import { createMDX } from fumadocs-mdx/next; const withMDX createMDX(); /** type {import(next).NextConfig} */ const config { output: export, reactStrictMode: true, }; export default withMDX(config);关键配置是output: export它开启了 Next.js 静态导出createMDX()则是 Fumadocs 的 MDX 集成插件负责在构建期把 MDX 内容编译为页面数据。3. 探索生成的项目结构模板说明将生成项目的可探索要点归纳为两个核心文件与一组路由文件/路由说明lib/source.ts内容源适配器代码其中的loader()提供访问内容的统一接口lib/layout.shared.tsx布局的共享配置可选但推荐保留app/(home)落地页及其他页面的路由组app/docs文档布局与文档页面app/api/search/route.ts搜索功能的 Route Handler3.1 内容源入口lib/source.ts在静态导出模板中lib/source.ts使用 Fumadocs 的 Macro API 定义集合collection这也是模板说明中特别提到的「Collections are defined with the Macro API」的具体落点。以结构完全一致的示例实现 examples/next-static/lib/source.ts 为例import { llms, loader } from fumadocs-core/source; import { docsContentRoute, docsImageRoute, docsRoute } from ./shared; import { defineDocs } from fumadocs-mdx/macro; import { metaSchema, pageSchema } from fumadocs-core/source/schema; const docs defineDocs({ dir: content/docs, docs: { schema: pageSchema, postprocess: { includeProcessedMarkdown: true, }, }, meta: { schema: metaSchema, }, }); // See https://fumadocs.dev/docs/headless/source-api for more info export const source loader({ baseUrl: docsRoute, source: docs.toFumadocsSource(), plugins: [], }); export const docsLlms llms(source, { renderPage: async (page) # ${page.data.title} (${page.url}) ${await page.data.getText(processed)}, });这里有两个关键 APIdefineDocs({ dir: content/docs })声明content/docs目录下的 Markdown/MDX 文件为文档集合metaSchema/pageSchema提供 frontmatter 字段校验loader()Fumadocs Headless Source API 的入口返回的source对象是整套文档系统的数据枢纽后续的页面渲染、搜索、OG 图片、LLM 文本导出都基于它。3.2 布局共享配置lib/layout.shared.tsx模板说明强调它「可选但推荐保留」。它把布局通用选项抽离成可复用的工厂函数避免在多个布局文件里重复粘贴配置。参考 examples/next-static/lib/layout.shared.tsximport type { BaseLayoutProps } from fumadocs-ui/layouts/shared; import { appName, gitConfig } from ./shared; export function baseOptions(): BaseLayoutProps { return { nav: { // JSX supported title: appName, }, githubUrl: https://github.com/${gitConfig.user}/${gitConfig.repo}, }; }它返回的是BaseLayoutProps导航标题、GitHub 链接等全局设置集中于此配合 examples/next-static/app/docs/layout.tsx 使用import { source } from /lib/source; import { DocsLayout } from fumadocs-ui/layouts/docs; import { baseOptions } from /lib/layout.shared; export default function Layout({ children }: LayoutProps/docs) { return ( DocsLayout tree{source.getPageTree()} {...baseOptions()} {children} /DocsLayout ); }source.getPageTree()根据内容文件自动生成文档导航树布局只需把baseOptions()展开传入即可。3.3 路由组与文档页面app/(home)路由组存放落地页模板默认生成一个极简首页参考 examples/next-static/app/(home)/page.tsx/page.tsx)内容指向/docs入口。app/docs则是文档区其动态路由页面 examples/next-static/app/docs/[[...slug]]/page.tsx 展示了静态导出模式下的核心模式export async function generateStaticParams() { return source.generateParams(); }这是静态导出的关键——generateStaticParams在构建期枚举content/docs下所有页面并逐一预渲染成 HTML从而保证out/目录里每个文档路径都有对应文件。页面本体则用source.getPage(params.slug)取数据、page.data.body渲染 MDX 内容并支持通过createRelativeLink实现文档内的相对文件路径互链。4. 静态站点的搜索无需后端的客户端全文检索模板路由表中列出的app/api/search/route.ts是搜索的 Route Handler但在静态导出模式下没有服务器运行时因此这里使用了 Fumadocs 的静态搜索方案。参考 examples/next-static/app/api/search/route.tsimport { source } from /lib/source; import { createFromSource } from fumadocs-core/search/server; export const revalidate false; export const { staticGET: GET } createFromSource(source, { // https://docs.orama.com/docs/orama-js/supported-languages language: english, });staticGET会在构建期把全部文档内容索引为静态 JSON 数据底层使用 Orama 作为索引引擎可通过language参数声明语言以启用对应的分词支持客户端则通过 examples/next-static/components/search.tsx 中的staticClient拉取该静态索引并在浏览器本地完成检索实现完全无后端、可被 CDN 托管的全文搜索体验。搜索对话框由 examples/next-static/components/provider.tsx 中的RootProvider注入到全局use client; import SearchDialog from /components/search; import { RootProvider } from fumadocs-ui/provider/next; export function Provider({ children }: { children: ReactNode }) { return RootProvider search{{ SearchDialog }}{children}/RootProvider; }5. 面向 SEO 与 AI 的静态产物OG 图片与 LLM 文本静态导出不仅适合人阅读模板生成的示例还内置了两条「机器可读」链路OG 图片app/og/docs/[...slug]/route.tsx参考 examples/next-static/app/og/docs/[...slug]/route.tsx在构建期用generateOGImage为每个文档生成一张包含标题、描述与站点名的社交分享图并在generateMetadata中通过openGraph.images注入到页面元数据让文档链接在社交平台上展示出精致卡片。LLM 文本lib/source.ts中的llms(source, ...)导出器会把文档渲染成纯文本格式供/llms.txt、/llms-full.txt、/llms.mdx等路由输出参见 examples/next-static/app/llms.txt/route.ts为 LLM 与 Agent 提供易于抓取的站点文本索引。这两类路由同样声明revalidate false确保构建期一次性生成静态内容。6. 构建、预览与部署完成写作后静态导出的完整发布链路如下# 1. 构建输出静态产物到 out/ npm run build # 2. 本地预览与线上 CDN 行为一致 npm run start # 3. 将 out/ 目录内容上传到任意静态托管/CDN其中out/目录对应当前项目 examples/next-static/next.config.mjs 中output: export的产物目录也已被 packages/create-app/template/nextfuma-docs-mdxstatic/example.gitignore 预先加入.gitignore同时忽略/.next/、/node_modules、.source等构建生成物。7. 局限与注意事项静态导出模式适合以内容为主的文档站但需要注意以下前提与限制无服务端动态能力所有数据必须在构建期确定revalidate、动态请求、服务端鉴权等运行时行为不可用搜索为客户端本地检索文档量极大时静态索引体积与客户端检索性能需要权衡可用language参数优化分词或评估分片方案图片与字体资源需要保证所有静态资源可被相对路径正确引用避免依赖服务端动态生成。从当前仓库的 examples/next-static 示例项目与模板同构的完整可运行版本包含app/(home)、app/docs、搜索、OG、LLM 路由及content/docs示例内容可以进一步查看每个文件的完整实现。总体而言nextfuma-docs-mdxstatic模板提供了一条「本地开发体验完整、产物零服务器、部署极其简单」的文档站路径非常适合托管在 CDN 上的开源项目文档与团队知识库。【免费下载链接】fumadocsThe beautiful flexible React.js docs framework.项目地址: https://gitcode.com/GitHub_Trending/fu/fumadocs创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考