Hugo + LoveIt 的 lastmod 为什么总显示成今天
一次被 Git 提交时间误导的排查记录

有些问题第一次看见时,并不难,难的是它长得太像另一个问题。
这次碰到的是 Hugo + LoveIt 里一个很小、但很容易把人带偏的细节:文章 front matter 里已经写了 lastmod = "2020-08-20T11:56:00+08:00",部署之后,内页却依然显示成“更新于 2026-03-17”。
表面上看,它像是主题没有读到字段;再往前走一步,又会很自然地怀疑是不是 LoveIt 有一个专门控制“最后更新时间”的开关。我一开始也是这么想的。

问题是怎么出现的
问题并不复杂:文章本身已经明确指定了 lastmod,而最终页面显示出来的日期却是部署当天。对一个习惯把文章时间写进 front matter 的人来说,这种结果会让人本能地认为,模板层没有按预期取值。
更容易让人误判的是,LoveIt 的页面文案本身就写着“更新于”。这几个字很容易把注意力引到主题表现层,好像真正出错的是某个显示选项、某段模板判断,或者某个没有打开的功能开关。
最开始我怀疑了什么
第一反应是去找主题配置里有没有类似 showLastmod、enableLastmod 之类的参数。因为从结果看,问题非常像“主题是否显示最后更新时间”的控制项没有配对。
第二反应是怀疑缓存或者部署残留。毕竟文章内容没有错,字段名也没有错,如果页面还在显示今天,最省力的解释往往就是:旧页面没被正确刷新。
但这两条路都没有把问题真正解释清楚。尤其是当页面稳定地显示成最近一次操作的日期时,事情开始显得不像前端表现异常,更像是上游数据本身就已经被改写了。

哪些表象其实是误导
最强的误导,其实正是“它看上去像主题问题”。LoveIt 负责把页面渲染出来,于是人很容易默认:既然显示不对,那就应该先去看主题。
但主题大多数时候并不负责决定日期从哪里来,它只负责把 Hugo 最终算出来的 .Lastmod 渲染出来。如果 Hugo 在更上游已经把 .Lastmod 解释成了别的值,那么主题展示得越正常,反而越容易让人误判方向。
另一个误导是“front matter 已经写了,所以它一定优先”。这件事在很多系统里成立,但在 Hugo 里,日期字段是有来源优先级的;只要存在优先级更高的数据源,手动写进文章的 lastmod 也不一定会成为最终显示值。
我看到了什么关键证据
真正把问题钉住的是站点配置里的这一段:
# 功能开关
# whether to use robots.txt
# 是否使用 robots.txt(利于SEO)
enableRobotsTXT = true
# whether to use git commit log
# 是否使用 git 提交信息(如文章最后修改时间)
enableGitInfo = true
# whether to use emoji code
# 是否使用 emoji 代码
enableEmoji = trueenableGitInfo = true 这行一出来,问题的性质就变了。它说明 Hugo 在构建时可以读取 Git 提交信息,而“最后修改时间”恰恰就是 GitInfo 最常介入的字段之一。
这时候再回头看现象,很多细节就突然顺了:为什么页面总是显示成最近一次部署前后的时间,而不是文章里写死的历史日期?因为那个“更新于”并不一定来自 front matter,它完全可能来自最近一次 Git 提交时间。

真正根因是什么
根因不是 LoveIt 不支持 lastmod,也不是 front matter 写法有问题,而是 Hugo 在计算 .Lastmod 时,会按照既定的来源顺序去选值。
在开启 enableGitInfo 的情况下,Git 提交时间会参与 .Lastmod 的计算;如果当前站点的 front matter 取值顺序里 :git 排在 lastmod 前面,那么最终页面显示出来的“更新于”就会被 Git 时间接管。
这也解释了为什么问题具有很强的迷惑性:文章里确实写了 lastmod,主题也确实正常显示了更新时间,只有中间那层“谁先谁后”的数据源优先级,在最开始并没有被看见。
最终修复方案是什么
这次我没有关闭 enableGitInfo,因为 Git 信息本身并不是问题,问题只是它在 lastmod 的取值链条里站得太靠前。
真正稳妥的修复方式,是显式告诉 Hugo:当文章 front matter 里写了 lastmod 时,先用它;只有没写的时候,才退回去读 Git 时间。配置可以直接改成下面这样:
# 功能开关
# whether to use robots.txt
# 是否使用 robots.txt(利于SEO)
enableRobotsTXT = true
# whether to use git commit log
# 是否使用 git 提交信息(如文章最后修改时间)
enableGitInfo = true
# whether to use emoji code
# 是否使用 emoji 代码
enableEmoji = true
# front matter 日期优先级
# 让文章 front matter 里的 lastmod 优先于 git 时间
[frontmatter]
lastmod = ['lastmod', 'modified', ':git', 'date', 'publishdate', 'pubdate', 'published']文章里的写法则保持不变:
lastmod = "2020-08-20T11:56:00+08:00"这样处理之后,页面显示的“更新于”就会回到文章里手动指定的日期;而在没有填写 lastmod 的内容上,Git 提交时间依然可以继续作为回退值存在。

这次排查最值得记住的经验是什么
第一,主题层和数据层要分开看。页面看起来像是主题显示错了,并不等于问题真的发生在主题里;很多“显示异常”其实是数据源选择异常。
第二,只要系统允许多个来源共同决定同一个字段,就不要想当然地认为“我手写的值一定优先”。真正可靠的判断方式,是把来源顺序找出来,看清它到底遵循谁的优先级。
第三,这类问题很值得留下复盘。因为它不是单点知识,而是一种排查路径:先承认表象会骗人,再把证据一层层收拢,最后把问题从“感觉像”变成“可以证实”。技术上真正让人进步的,往往就是这一步。
梦行志