你”ChatGPT 插件”那篇 2023 年发的。上个月重写过——新截图、新模型名、新例子——但 frontmatter 的 publishedAt 还是 2023-03-14。SERP 在你标题旁显示”Mar 14, 2023”——读者跳过你选看起来更新鲜的对手——Google 把它当陈旧降权。文章其实被刷新了,日期没动而已。
反向陷阱一样糟:每次小修都把 publishedAt 撞到今天——所有文章看起来都刚发——Google 读出来是 date-spam 直接降权。正解:两个字段、明确的刷新策略、对合理需要频繁更新的话题加 volatile flag。
常见原因
1. 只有一个日期字段——永不动
schema 只有 publishedAt,没 updatedAt。所以日期要么永不动(看起来陈旧)要么撞(看起来 date-spam)——都错。
如何判断:查 content collection schema 有没有 updatedAt。没有——你的设计本身就有这病。
2. updatedAt 有但作者不更新
schema 有 updatedAt 但作者真刷文章时忘了撞——页面 header 显示”Updated: 2023-03-14”——但文章上周才重写。
如何判断:比 git log mtime 和 frontmatter 的 updatedAt。git mtime 比 updatedAt 新 6 个月+——错标陈旧。
3. 每次小修都撞日期
作者改个错别字、撞 updatedAt 到今天;一周后再改个错别字、再撞。文章一年没实质改动但 updatedAt 周周动——Google 注意到。
如何判断:看 git log -p 中 updatedAt 的变更。80% 撞动都是单行 diff——你有 date-spam。
4. 快变话题没标 volatile
“当前 ChatGPT 定价”——天然每季度过期。没有 volatile: true flag——它和常青内容一起被同样对待——应该按计划刷新。
如何判断:列含”current”/“latest”/“2024”/“pricing”/“limits”等关键词的文章——没 volatile flag 就该加。
5. Schema markup 用错日期
JSON-LD 的 datePublished 和 dateModified 都取自 publishedAt。Google 的新鲜算法读 dateModified——有 updatedAt 但 JSON-LD 不用——SERP 日期反映不出刷新。
如何判断:view-source 看一篇刷新过的——查 JSON-LD 块:
curl -s https://site.com/en/articles/your-slug/ | grep -A2 'dateModified'
dateModified 和老发布日期一样——schema 错了。
最短修复路径
Step 1:加一个真的 updatedAt 字段
更新 content collection schema,要求两个:
// src/content/config.ts
import { z, defineCollection } from "astro:content";
const articles = defineCollection({
schema: z.object({
title: z.string(),
publishedAt: z.date(),
updatedAt: z.date().optional(),
volatile: z.boolean().default(false),
// ...
}),
});
publishedAt 首次发布时一次性设定、永不动。updatedAt 实质刷新时设(不是错别字)。
Step 2:JSON-LD + 可见日期都接 updatedAt
article layout 里显示最近那个,并发到 JSON-LD 的 dateModified:
---
const { article } = Astro.props;
const lastUpdate = article.data.updatedAt ?? article.data.publishedAt;
---
<time datetime={lastUpdate.toISOString()}>
Updated {lastUpdate.toLocaleDateString()}
</time>
<script type="application/ld+json" set:html={JSON.stringify({
"@context": "https://schema.org",
"@type": "Article",
datePublished: article.data.publishedAt.toISOString(),
dateModified: lastUpdate.toISOString(),
// ...
})} />
SERP 显示刷新日期、Google 新鲜算法看到真动作。
Step 3:定义刷新策略
写下何时该撞 updatedAt:
- 实质:加新章节、模型/定价事实更新、代码示例重写、换截图——撞
- 小修:错别字、措辞润色、加内链——不撞
- 只修对端翻译漂移:不撞(被刷的那一端各自处理)
reviewer 在 PR 上执行——小修 PR 撞了日期就给”恢复日期”评论。
Step 4:标 volatile 文章
定价、模型清单、“X 的当前状态”类——加 volatile: true:
---
title: "Current ChatGPT Pricing"
volatile: true
updatedAt: 2026-05-24
---
季度脚本扫所有 volatile: true 且 updatedAt 超 90 天的——成为你的刷新队列。
# scripts/audit-volatile-staleness.mjs
import fs from "node:fs";
import matter from "gray-matter";
const THRESHOLD_DAYS = 90;
const now = Date.now();
for (const f of /* 遍历文章 */ []) {
const { data } = matter(fs.readFileSync(f, "utf8"));
if (!data.volatile) continue;
const last = new Date(data.updatedAt || data.publishedAt).getTime();
const ageDays = (now - last) / 86400000;
if (ageDays > THRESHOLD_DAYS) {
console.log(`STALE volatile: ${f} (${Math.round(ageDays)}d old)`);
}
}
Step 5:一次性回填存量陈旧标签
跑一次一次性回填:
1. 列 git mtime 比 publishedAt 新 6 个月+ 的
2. 每篇判断:是不是真实质刷新过
3. 是——把 updatedAt 设为合理近期日期(最后一次大编辑的 git mtime)
4. 否——别动
不要把所有文章撞到今天。挑过的、可辩护的日期。
预防
- 两字段 schema:
publishedAt不变、updatedAt配刷新 volatile: true配时间敏感话题——季度刷新队列- 文档化刷新策略——reviewer 在 PR 上执行”实质 vs 小修”
- JSON-LD
dateModified接updatedAt,不是publishedAt - 审计脚本扫 90 天+ 没刷的 volatile 文章
- 用 git history 当真相一次性回填真实刷新过的文章
相关
- Stale Articles Not Updated
- Content Site Sitemap Not Resubmitted After Big Changes
- Outdated Screenshots in Tutorials
- Content Site FAQ Schema Not Extracted
- Content Site Hreflang Tags Misconfigured
- Content Site Canonical Points to Self Wrong
标签: #内容运营 #站点质量 #站点审计 #排查 #publish-date