
Quartz NotFoundPage 插件详解为不存在的 URL 生成干净的 404 错误页【免费下载链接】quartz a fast, batteries-included static-site generator that transforms Markdown content into fully functional websites项目地址: https://gitcode.com/GitHub_Trending/qua/quartz导读NotFoundPage是 Quartz 内置的页面类型Page Type插件专门为损坏或不存在的 URL 生成 404Not Found错误页。它以minimal页面框架无侧边栏、无头部或 beforeBody 装饰仅保留内容与页脚呈现一个干净的错误页面。读完本文你将掌握该插件的工作机制、与 SPA 路由和minimal页面框架的协同原理、其基于 i18n 的多语言文案机制以及如何验证 404 页面在本地开发与生产部署两种环境下的资源路径处理差异。插件定位无需配置的兜底页面类型在 Quartz 的插件体系中NotFoundPage属于Page Type页面类型类别其官方定义为This plugin emits a 404 (Not Found) page for broken or non-existent URLs.它的核心设计哲学是零配置——文档明确指出 This plugin has no configuration options.。这意味着你不需要在quartz.config.ts中为它写任何参数它默认且始终启用。事实上从源码看它是构建流程内置的兜底页类型quartz/plugins/loader/config-loader.ts中的builtinPageTypes [builtinPlugins.PageTypes.NotFoundPageType()]将其固定追加到所有构建任务中无论你的站点是否配置了其他页面类型插件404 页都会被生成。API 速览项目值类别Page Type页面类型函数名Plugin.NotFoundPage()内部插件源码quartz/plugins/pageTypes/404.ts页面 slug404布局标识layout: 404页面框架minimal优先级-1从文档到源码NotFoundPage 的完整实现文档对插件的描述非常精炼但其背后有完整的源码实现可供深入解读。让我们从 quartz/plugins/pageTypes/404.ts 的完整定义出发export const NotFoundPageType: QuartzPageTypePlugin () ({ name: 404, priority: -1, match: match.none(), generate({ cfg }) { const notFound i18n(cfg.locale).pages.error.title const slug 404 as FullSlug const [, vfile] defaultProcessedContent({ slug, text: notFound, description: notFound, frontmatter: { title: notFound, tags: [] }, }) return [ { slug, title: notFound, data: vfile.data, }, ] }, layout: 404, frame: minimal, body: NotFound, })几个关键点值得展开match: match.none()该插件的匹配器永远不会匹配任何真实文件。match.none()来自 quartz/plugins/pageTypes/matchers.ts恒返回false。它不参与普通页面的分发而是通过generate()直接生成一个 slug 为404的虚拟页面virtual page。priority: -1在所有页面类型中它的优先级最低。在 quartz/plugins/pageTypes/dispatcher.ts 中页面类型按优先级降序排序因此 404 页总是最后被处理确保其不会干扰其他页面类型的匹配。frame: minimal显式声明使用 minimal 页面框架这是文档所述无侧边栏、无头部、无 beforeBody 装饰的直接来源。generate()返回值它构造一个内容为 i18n 错误标题默认英文 Not Found的虚拟 vfile生成器最终产出{ slug: 404, title: Not Found, data: ... }。404 页的标题文案同样来自 i18n 配置而非硬编码。为什么 404 页是虚拟页面而非真实文件在 quartz/plugins/pageTypes/dispatcher.ts 的三阶段发射流程中404 页属于 Phase 1 生成的虚拟页面Phase 1调用所有页面类型的generate()生成虚拟页面条目并填充ctx.virtualPages注意 dispatcher.ts#L196-L198 中特意将vpSlug ! 404的页面才加入virtualPages404 页不参与转写嵌入Phase 2发射普通真实页面通过pt.match()匹配Phase 3发射所有虚拟页面404 页在此阶段写出为404.html。minimal 页面框架干净错误页的渲染基础文档强调 404 页使用 minimal 页面框架no sidebars, no header or beforeBody chrome — only content and footer。这一点在 quartz/components/frames/MinimalFrame.tsx 中有清晰实现export const MinimalFrame: PageFrame { name: minimal, render({ componentData, pageBody: Content, footer }: PageFrameProps) { return ( div classcenter minimal Content {...componentData} / /div {footer.map((FooterComponent) ( FooterComponent {...componentData} / ))} / ) }, }可见 minimal 框架只渲染两样东西一个center minimal容器包裹的页面主体即 404 组件本身页脚footer组件列表——保留页脚是为了承载法律/链接义务源码注释原文plus the footer for legal/link obligations。与之对比quartz/components/frames/types.ts 中说明页面框架定义了#quartz-root外壳内部的具体 HTML 结构不同框架default、full-width、minimal可以产生完全不同的布局而外部外壳html、head、body、quartz-root保持稳定以便 SPA 导航。这正是 404 页能呈现干净错误页的底层机制。框架优先级与解析从 quartz/plugins/pageTypes/dispatcher.ts#L19-L38 的resolveLayout可以看出框架解析的优先级配置覆盖config override 页面类型声明pageType.frame 默认default404 插件在自身声明frame: minimal因此只要你在配置中没有为 404 布局强制指定其他框架它就会走 minimal。404 页面组件内容、i18n 与大小写重定向404 页的实际渲染由 quartz/components/pages/404.tsx 完成。它导出的是一个QuartzComponent被 404 插件通过body: NotFound挂载为页面主体。组件结构如下const NotFound: QuartzComponent ({ cfg, ctx }: QuartzComponentProps) { const url new URL(https://${cfg.baseUrl ?? example.com}) const baseDir ctx.argv.serve ? / : url.pathname return ( article classpopover-hint h1404/h1 p{i18n(cfg.locale).pages.error.notFound}/p a href{baseDir}{i18n(cfg.locale).pages.error.home}/a script dangerouslySetInnerHTML{{ __html: ... }} / /article ) }多语言文案i18n错误页的三段文案全部来自 i18n 配置cfg.locale以 quartz/i18n/locales/en-US.ts 为例pages: { error: { title: Not Found, notFound: Either this page is private or doesnt exist., home: Return to Homepage, }, ... }pages.error.title→ 404 页的标题也用于生成 vfile 与h1之外的文件标题pages.error.notFound→ 正文提示Either this page is private or doesnt exist.该页面要么是私有的要么不存在pages.error.home→ 返回首页链接的锚文本。仓库的 quartz/i18n/locales 目录提供了 30 多种语言的翻译因此切换到中文等其他 locale 时404 页文案会自动本地化。大小写容错重定向脚本组件内嵌了一段客户端脚本其作用是对大小写不一致的 URL 做智能重定向。它读取document.body.dataset.basepath获取站点基础路径剥离路径前缀、开头的/、结尾的/与.html//index后缀后将路径小写化再在站点内容索引fetchData中查找小写版本是否存在若存在则通过window.location.replace(target)重定向到正确的小写路径。这为因 URL 大小写错误而看似 404的请求提供了自动修复能力避免了用户遇到错误的 404 提示。关键工程细节404 页的资源路径处理一个值得注意的实现细节是 quartz/plugins/pageTypes/dispatcher.ts#L82-L92 中emitPage对 404 页的特殊 baseDir 处理const baseDir slug 404 ? ((ctx.argv.serve ? / : new URL(https://${cfg.baseUrl ?? example.com}).pathname) as FullSlug) : pathToRoot(slug)注释解释了原因当托管服务商在任意 URL 深度提供 404.html 时必须使用绝对基础路径资源才能正确解析。例如 GitHub Pages 在子路径下部署站点baseUrl为https://user.github.io/repo/时用户访问任意深层失效链接都会拿到 404 页若 404 页内资源使用相对路径就会指向错误位置。同时本地开发--serve模式下 dev server 会自行剥离 baseDir 并从根路径提供文件因此 404 页必须使用/以避免在路径前缀下请求不存在的资源。这个分支逻辑保证了 404 页在两种环境下资源引用都正确。与 SPA 路由的协同Quartz 默认启用单页应用SPA式渲染参见 docs/features/SPA Routing.md通过劫持页面导航、用GET请求抓取 HTML 并利用 micromorph 做局部 diff 替换避免整页刷新。SPA 脚本由 quartz/plugins/emitters/componentResources.ts 在cfg.enableSPA为真时注入配置项定义在 quartz/cfg.ts默认值true见 quartz/cli/plugin-data.js 与各模板如 quartz/cli/templates/default.yaml。在 SPA 模式下用户访问不存在的内部链接时fetchData索引中查不到目标便会加载 404 页内容——此时 404 组件内置的脚本与popover-hint等机制协同保证错误提示与返回首页链接正常运作。若要关闭 SPA 行为可将quartz.config.yaml中的enableSPA设为false但这不会影响 404 页本身——它始终由构建流程生成。验证与实战建议确认产物构建后检查输出目录中存在404.html文件npx quartz build后位于public/404.html这是插件生效的最直接证据。本地验证运行npx quartz build --serve访问任意不存在的路径如/nonexistent-page应看到 404 组件渲染的 Not Found 页面且资源路径指向/。部署验证部署到 GitHub Pages、Netlify、Vercel 等平台后访问深层失效 URL确认页面样式与资源正常加载——这正是 dispatcher 中绝对 baseDir 分支所保障的。多语言验证将locale配置切换为zh-CN等语言参考 quartz/i18n/locales/zh-CN.ts重建后 404 页文案应随之本地化。相关资源插件文档docs/plugins/NotFoundPage.md插件实现quartz/plugins/pageTypes/404.ts页面分发器quartz/plugins/pageTypes/dispatcher.ts页面框架类型定义quartz/components/frames/types.tsminimal 框架实现quartz/components/frames/MinimalFrame.tsx404 页面组件quartz/components/pages/404.tsx插件配置总览docs/configuration.mdSPA 路由特性docs/features/SPA Routing.md【免费下载链接】quartz a fast, batteries-included static-site generator that transforms Markdown content into fully functional websites项目地址: https://gitcode.com/GitHub_Trending/qua/quartz创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考