排错与检查
构建、语言、搜索、平台四类故障的症状 → 原因 → 修法,以及站点可以自己跑的那几项检查。
出问题时先做一次干净的生产构建,从第一条错误开始看,后面的多半是级联结果:
终端
日志里出现 npm、PostCSS、Autoprefixer 或下载浏览器资源的步骤,说明配置里混进了上游 Docsy 的流程。OINK 消费端的构建只有一条 Hugo 命令。
下面四张表按「症状 → 原因 → 修法」组织,找到症状那一行即可,不必从头读。
构建
| 症状 | 原因 | 修法 |
|---|---|---|
| 构建报要求更高的 Hugo 版本 | 装的是标准版而不是 Extended,或版本低于 0.160.1 | hugo version 输出里必须有 extended。多个 Hugo 共存时先查 PATH 与版本固定配置,而不是再装一份 |
module "github.com/pgsty/oink" not found |
主题没解析出来 | Hugo Module:看 hugo mod graph、go.mod、go.sum,以及有没有多余的 workspace / replace。submodule:CI 有没有在 Hugo 之前跑 git submodule update --init。归档 / 克隆:theme: 的值要与 themes/ 下的目录名一致 |
| 模块下载卡住或超时 | Go 的模块代理不通 | Hugo 通过 Go 拉模块,所以走 GOPROXY。国内网络可以 export GOPROXY=https://goproxy.cn,direct;隔离环境改用离线归档或提交 themes/oink/ |
页面上出现 {.cards}、{.steps}、{caption=…} 这类原样文字 |
站点没开 goldmark 的块级属性 | 站点的 hugo.yml 里必须有下面那三项,主题的 markup 配置不会被 Hugo 合并进来 |
图片带属性行时被包进了 <p>,图注没生效 |
缺 wrapStandAloneImageWithinParagraph: false |
同上,三项一起加 |
| 行内 HTML 被转义成文字 | 缺 renderer.unsafe: true |
同上 |
\(…\) $$…$$ 原样显示 |
站点没启用 goldmark passthrough | 见公式;math: true 不是启用开关 |
shortcode "tabs" must be closed or self-closed |
有 {{< tabs >}} 没写对应的 {{< /tabs >}} |
报错里带 文件:行:列,去那一行补上闭合标记 |
template for shortcode "tabs" not found |
正文里写了一个不存在的 shortcode,或引用 shortcode 语法时没有转义 | 文档里讲解 shortcode 语法时必须转义:在开标记与闭标记的内侧各加一对 /* 与 */,Hugo 才会把它当文字而不是调用。名字打错就改回正确的名字 |
... attributes: unknown attribute "witdh" at ... |
属性行里的键拼错或不被允许 | 属性行只接受该组件的允许键、class、data-*、aria-*;style 与 on* 一律构建失败。允许的键就写在报错括号里 |
shortcode "field": unsupported parameter "colour" at ... |
shortcode 参数名不对 | 组件参数——shortcode 参数与属性行的键——一律构建失败,不做静默降级。报错格式固定为「哪个 shortcode → 哪个参数 → 哪个文件的第几行」,照着改即可 |
invalid params.ui.page_width "widee" (allowed: normal | wide | full) -- using "normal" |
配置或 front matter 的取值,不在允许集合里 | 配置类的错误降级而不中断,一个笔误不会让 hugo server 下每个 URL 都返回 500。消息里带键名、收到的值和实际用的回退值。构建加 --panicOnWarning,它就上不了线 |
| 某个页面设置不生效,也没有任何提示 | 键写在了 front matter 的 ui: 段里 |
页面键写在 front matter 顶层,键名是站点键去掉 ui.。写进 ui: 段的键没有人读,也没有人报错,见页面参数 |
| 构建通过但线上少东西 | 有 WARNING 没人看 | 构建命令加 --panicOnWarning。非法配置取值、giscus 必填键缺失、不支持的 comments.type、Hugo 的弃用提示都只是告警 |
那三项 goldmark 配置:
hugo.yml
两个最常见的 shortcode 报错长这样,注意结尾的 文件:行:列:
构建输出
语言
| 症状 | 原因 | 修法 |
|---|---|---|
| 译文页面不出现 | 四种可能,按顺序查 | ① hugo.yml 里有 languages.zh 且设了 weight;② 文件名是 page.zh.md,zh 必须小写;③ 译文 front matter 没有 draft: true,date 不在未来;④ 影响路由的元数据与源文件一致 |
| 语言切换跳到了首页 | Hugo 没找到对应译文 | 这是设计行为:找不到译文就回退到目标语言首页。要跳到对应页面,需要那个译文文件确实存在 |
| 锚点链接打开了页面却不定位 | 译文标题文字不同,自动生成的 ID 也不同 | 在译文标题上显式写英文 ID:## 安装 {#installation}。标题里含 shortcode 或行内 HTML 时不要凭文本猜 ID,去看英文页渲染出来的 HTML |
| 菜单 / 首页分区没翻译 | 这些不在页面里,在配置和数据文件里 | 菜单在 languages.<lang>.menus,首页分区在 data/home/<lang>.yaml,界面字符串在 i18n/<lang>.yaml,见多语言 |
中文页 hreflang 指向英文首页 |
该页没有英文对等文件 | 补上英文页,或接受这个回退:它同时是「Hugo 有没有认出译文关系」的探针 |
搜索
| 症状 | 原因 | 修法 |
|---|---|---|
| 搜索框有但一直没结果 | 索引没生成 | params.offline_search: true 之后,产物根目录下应该有 offline-search-index.<语言>.json,每种语言一份。没有就是没开 |
| 索引文件请求 404 | baseURL 不对 |
子路径部署下 baseURL 配错是索引 404 最常见的原因。先在浏览器网络面板看它去哪里取索引,见发布上线 |
hugo server 下搜不了,构建出来就正常 |
站点把预览期的索引关掉了 | params.offline_search_on_serve 默认为 true,预览与线上行为一致;配置里显式写成 false 时预览不生成索引,删掉或改回 true |
| 中文搜不到 | 多数不是分词问题 | 中文查询走主题的 CJK 子串回退。先确认那个中文页面的内容进了中文索引(打开 offline-search-index.zh.json 查一下),再看分词 |
| 新页面搜不到,旧页面正常 | 索引是构建产物 | 重新构建。hugo server 下改了页面要等它重建完 |
params.search.algolia requires explicit appId, apiKey, and indexName values |
Algolia 三个键没配全 | 三个键必须显式给全,主题不会替你用别的项目的 DocSearch 凭据。不用 Algolia 就把这段配置删掉 |
| 命令面板搜不到内容 | 它与全文检索是两件事 | 索引不可用时命令面板仍然能打开,只是提示索引不可用,页面操作与命令照常,见命令面板 |
平台
| 症状 | 原因 | 修法 |
|---|---|---|
| GitHub Pages 上页面 404 或样式全丢 | 项目站点的 URL 带仓库路径,baseURL 没带 |
用工作流里的 --baseURL "${{ steps.pages.outputs.base_url }}/",别手写。完整工作流见发布上线 |
| GitHub Pages 上「最后修改时间」「贡献者」全空 | checkout 是浅克隆 | actions/checkout 加 fetch-depth: 0:enableGitInfo 要读完整历史 |
| Cloudflare Pages 构建报 Hugo 版本太低 | 构建镜像的默认 Hugo 低于主题要求 | 在 Production 和 Preview 两个环境都设 HUGO_VERSION,并设 SKIP_DEPENDENCY_INSTALL=1 |
| 托管商构建时拉不到主题 | 构建环境没有 Go | Hugo Module 需要 Go。平台不提供就改用 submodule 或把 themes/oink/ 提交进仓库 |
| CI 上构建结果和本地不一样 | go.work 参与了 CI 构建 |
CI 里设 GOWORK: off 与 HUGO_MODULE_WORKSPACE: off,让它只认 go.mod 里固定的版本 |
| 预览部署被搜索引擎收录了 | 预览也用了 production 环境构建 | 预览构建不要带 --environment production,非 production 自带 noindex 与 Disallow: /,见分析与 SEO |
| macOS 报打开文件过多 | 实时预览监视的文件超过了 shell 限制 | 先把生成目录与无关目录排除出监视范围,这通常才是根因;再考虑 ulimit -n |
| WSL 下很慢或漏掉改动 | 跨 Windows 挂载点工作 | 让 Hugo 处理 Linux 文件系统里的路径,跨文件系统的变更通知和权限行为会让实时重载失效 |
| 缺 Bootstrap / Font Awesome / Lunr / Mermaid 之类资源 | 发行物不完整 | 不要用 CDN URL 掩盖。确认 assets/third_party/、assets/js/third_party/、static/webfonts/、VENDOR.json 都在;确实缺就重新获取同一个固定版本 |
站点自带检查
除了构建本身,站点还可以自己跑这几项。前两条任何 OINK 站点都能用,后面几条是本仓库的 npm 脚本,其它站点跑等价的检查即可。
npm test 里的六项各管一段:
test:base— 先构建一次,再跑 Markdown 风格、翻译对等、渲染后的 Markdown 与链接检查。test:hugo-build— 构建断言:博客元数据、RSS、内容组件、构建过程零弃用提示。test:md-output— Markdown 与llms.txt输出的 golden 比对,字节级。改了组件的 Markdown 形态就会在这里挂。test:alt-site— 用tests/fixtures/*.yml里的替代配置各构建一次,确认不同配置组合都能起来。test:favicons— head 输出的 golden 比对。test:release-pin-contract— 站点公告的版本与go.mod固定的版本是否一致。
浏览器行为另开一套:npm run test:browser 依次跑 Playwright 的无障碍(axe WCAG AA)、响应式外壳、键盘导航、内容组件、代码块与场景组件六个套件。
check-output-security.py 在主题仓库里它在主题仓库的 bin/ 下,是产品级的信任检查,任何 OINK 站点都可以跑,不依赖站点的测试框架。克隆主题仓库后指向自己的 public/ 即可,参数与用法见断网构建验证。
诊断习惯
上面的表覆盖不到的问题,按这几条挖:
- 用固定的 Hugo Extended 版本复现,不在版本浮动的环境里判断。
- 清掉
public/与resources/_gen再重建,排除陈旧缓存。 - 对比开发与生产两套配置层,很多只在线上出现的问题是环境差异。
- 看第一条错误,不是最后那条。
- 用一个最小页面区分「主题行为」和「站点覆盖」:把可疑内容单独放一页,站点覆盖分批重新启用,定位到具体那一项。
- 看故障页面的浏览器控制台与网络面板,尤其是 404 的资源路径。
求助渠道
开 issue 时带上这几样,能省掉一轮来回:Hugo 版本(hugo version 完整输出)、主题版本(hugo mod graph | grep oink)、第一条完整错误、能复现的最小页面或最小站点。
- 主题与文档的问题:https://github.com/pgsty/oink/issues
- 本站内容的问题:https://github.com/pgsty/oink.pgsty.com/issues
- 上游 Docsy 的兼容性讨论:https://github.com/google/docsy/discussions
相关
- 本地预览 — 干净构建、清缓存、容器与工作区
- 发布上线 —
baseURL、验收清单与回滚 - 版本升级 — 升级引入的问题与迁移工具
- 全文检索 — 索引范围、权重与 Algolia
- 多语言 — 语言配置与锚点对齐流程