静态站的标签体系:挖出 11 个可收录页面
做体检时随手查了一下「标签页在不在」,结果发现两件事:没有标签页,而且文章页上也看不到标签。
后者更意外:文章页明明写了 <PostMetadata tags={entry.data.tags} />,但那个组件里根本没有 tags 字段——传进去的参数被静默忽略了。于是 20 个标签只活在 frontmatter 里,对读者和搜索引擎都不存在。
先数一遍:哪些标签值得建页

建站 18 篇 · Astro 11 篇 · 性能 8 篇 · 安全 6 篇
运维 3 篇 · Cloudflare 3 篇 · 统计 2 篇 · 观测 2 篇 · 工程实践 2 篇 · 隐私 2 篇
以下各 1 篇:缓存 / 图片 / SEO / 搜索 / 公告 / HTTPS / 网络 / 排障 / 测量 / 成本
规则很简单:只给 ≥2 篇文章的标签建落地页。
单篇标签的聚合页只有一篇文章 + 一句导语,是标准的薄内容——Google 对这类页面没有好感,而它又会让站内多出 10 个”看起来像页面但没内容”的 URL。所以单篇标签只显示在文章底部(纯文本,不带链接),不建页、不进 sitemap。
最终:10 个标签页 + 1 个索引页 = 11 个新页面,可收录页面从 30 个涨到 41 个(+37%)。
每个标签页长什么样

以 /tags/Astro/ 为例,一个页面要有四样东西:
- 独立的 title / description(不能复用文章页的,也不能所有标签页共用一句);
- 单 h1 —— 由布局的
heading属性渲染成<h1 class="sr-only">,可见标题用 h2; - 结构化数据 ——
CollectionPage+ItemList,把该标签下的文章作为itemListElement; - 内容本身 —— 按时间倒序的文章列表 + 页脚「其他标签」交叉链接。
结构化数据那段值得单独说:标签页的价值是”聚合”,所以用 CollectionPage,而不是 BlogPosting。ItemList 里最多放 20 条,标题直接取文章标题、URL 取绝对地址。
描述怎么生成:唯一、且够长
第一版我自动生成的是:
peroe 的博客中带有「统计」标签的 2 篇文章,按发布时间从新到旧排列。
体检立刻报「description 38 字(建议 60~160)」。而且 10 个标签页都是同一个句式,只有标签名不同——这是重复内容。
改成用该标签下最新两篇文章的标题拼摘要:
peroe 的博客中带有「Astro」标签的 11 篇文章…… 例如:《Astro 静态站的三个隐形约定:CSS 是全局的》、
《静态站的标签体系:挖出 11 个可收录页面》。每篇都附带实测数据与可复现的命令。
结果是每页 100~130 字、彼此唯一,而且自然带上了文章关键词。这也是我后来给「相关文章」组件定描述时用的同一个思路:让自动生成的文案里带真实内容片段。
三个坑

坑一:getStaticPaths 里不能提前编码。
// ❌ 构建直接失败:NoMatchingStaticPathFound: /tags/建站/
params: { tag: encodeURIComponent(tag) }
// ✅ 给原始标签名,Astro 会解码 URL 后再匹配
params: { tag }
这是中文标签必踩的一脚:链接里需要 encodeURIComponent(浏览器行为),但路由参数不能。
坑二:审计脚本对中文路径的 canonical 误报。
/tags/统计/ 的 canonical 是 https://blog.peroe.cn/tags/%E7%BB%9F%E8%AE%A1/ —— 两者等价,但我自己的体检脚本是逐字符比较,于是报了 10 条「canonical 指向别处」。改成比较前先 unquote() 两边,误报清零。
写体检脚本的人容易犯这个错:URL 比较必须按语义比,不能按字符串比。
坑三:sitemap 是手写清单。
新页面建好了但 sitemap 里没有——它不会自己出现。我维护的是一份 staticPages 清单,得手动补 /tags/,再按「≥2 篇」的同一条件生成 10 条标签页条目(lastmod 取该标签下最新文章的更新时间)。建页条件必须和 getStaticPaths 完全一致,否则 sitemap 里会混进 404。
顺带修的一件事:文章页显示标签
标签页有了,但读者是从文章页过来的——所以给 PostMeta 加了标签渲染:
{tags.map((tag) =>
linkableTags.includes(tag)
? <a href={`/tags/${encodeURIComponent(tag)}/`}>{tag}</a> // ≥2 篇:可点
: <span>{tag}</span> // 单篇:纯文本
)}
linkableTags 在构建期算好(复用同一份统计),这样单篇标签不会产生 404。
小结
标签体系的价值有两层:
- 对读者:从一篇文章跳到同主题的其他文章;
- 对搜索引擎:多出 11 个主题聚合页,能吃「Astro 建站」「网站性能优化」这类单篇标题命中不了的词。
判断标准可以总结成三条:
- ≥2 篇才建页(薄内容不建);
- 描述必须唯一且够长(拼真实标题,别套模板);
- 建页条件在
getStaticPaths、sitemap、链接渲染三处保持一致(否则不是 404 就是孤儿页)。
标签页与站点地图的联动细节,见博客 SEO 自我体检那一篇里的体检清单。
发现错误或想要改进这篇文章?
在 GitHub 上编辑此页文章修订历史 (1 次)
查看变更记录
docs(baseline): 第 30 轮终检——数字更新到最终状态,补第 28~30 轮小结
相关文章
- 博客 SEO 自我体检:27 个页面里揪出四个系统性毛病不靠站长后台,直接扫构建产物做 SEO 体检:发现全站 h1 数量为 0、28 个页面都没有 og:image、静态页共用同一段描述、404 页输出了两份 head。附体检清单与修法。
- 首屏从 392KB 砍到 59KB,FCP 从 7.4 秒到 2.1 秒用 CDP 模拟中端手机实测博客首页:GA4 与 Clarity 挤在关键路径、头像和 favicon 直接加载 107KB 原图、312KB 关键 CSS 拖慢首屏。四处改动后传输 392KB→59KB,FCP 7.4s→2.1s,长任务 13→2 个。
- 24 篇文章的站内 SEO:一套可复跑的体检清单不靠站长后台、不装插件,写一个脚本扫构建产物就能查出大部分站内 SEO 问题。这篇是 24 篇文章、54 个页面跑下来整理出的八项检查、九类真实问题与修法,以及三条「体检本身也会骗你」的教训。