如果说第一篇写的是“这个博客终于能部署出去了”,那第二篇更像是在处理另一个迟早要面对的问题:文章到底该怎么命名,URL 到底该怎么长。
最开始的做法很省事,文章目录直接按日期建,比如 20260308。这样当然能用,但问题也很快暴露出来了。
第一,一天可能不止写一篇。第二,这个目录名会直接变成文章 URL。第三,纯日期作为链接虽然整齐,但既不直观,也谈不上对长期维护友好。
本地组织内容和对外暴露链接,本来就不是同一回事。之前我把这两件事绑在一起,只是因为项目刚开始,还没有感受到它们分开之后能带来的好处。
等真的开始写第二篇时,这个问题就已经没法继续装作不存在了。
目录名和 URL,不该是同一个东西
我后来越来越确定,文章系统里至少有两种“名字”:
- 给作者自己看的内容目录名
- 给读者和搜索引擎看的访问 URL
这两者的目标其实完全不同。
目录名更适合追求可读性。比如 2026-03-08-折腾这个博客的第一夜,我一眼就知道这是什么、是哪天写的,也方便以后直接在文件系统里找文章。
但 URL 就不一定要背这个包袱。它更重要的是稳定、可控,而且不要因为目录改名或者标题变动就跟着漂移。
所以最后定下来的方案是:
- 目录:日期 + 中文标题
- URL slug:单独维护
像今天这两篇文章,目录会是:
2026-03-08-折腾这个博客的第一夜2026-03-08-把文章 URL 从目录里拆出来而它们对外的 URL 会是:
20260308-0120260308-02这套规则其实很朴素,但它一下子把几个问题都顺手解决了。
不想手动想 slug,那就让 slug 只负责稳定
一开始我也在纠结,到底要不要用更“像 SEO”的语义化 slug。比如英文关键词、短标题、甚至标题转拼音之类的方案。
想了一圈之后,我反而更清楚自己真正想避免的是什么:
- 不想每次写文章都额外想一遍 slug
- 不想为了 URL 去牺牲本地目录的可读性
- 不想以后改标题时担心链接是否会一起变化
既然如此,那 slug 最适合扮演的角色就不是“语义表达”,而是“稳定编号”。
20260308-01 这种形式有一个很实际的好处:它不需要我额外决策。
写文章时,最稀缺的其实不是生成 slug 的技术能力,而是注意力。能省掉的决策,就应该省掉。让脚本自动给我一个当天递增编号,比让我每次都花几十秒想一个“以后看起来也不会后悔”的链接名字,要合理得多。
有时候,好的工程设计不是提供更多可选项,而是替你拿掉那些其实没有价值的选择。
真正的改造,不是脚本,而是把整条链路都换掉
表面上看,这次像是在改新建文章脚本。
但只改脚本其实没用,因为这个博客原来的文章路由逻辑本身就把内容目录当作 public slug 在用。换句话说,如果只改了创建目录的规则,不把后面的读取和链接生成一起改掉,最终只是把问题换个地方继续存在。
所以这次真正动到的是整条链路:
- 内容 schema 增加
urlSlug字段 - 新建文章时自动写入
urlSlug - 页面静态路由改成按
urlSlug生成 - 上一篇 / 下一篇跳转也跟着用
urlSlug - RSS 输出链接统一切到
urlSlug - 首页和归档页的文章卡片也统一用新链接
这样改完之后,目录改名和 URL 就彻底分开了。
以后我哪怕把目录从中文改成英文、从单层改成多层,只要 urlSlug 不变,站点外部链接就不需要跟着动。对博客这种长期会不断调整结构的项目来说,这一点比它看上去重要得多。
一个小改动,顺手暴露了几个真实的类型问题
这次改造还有一个很典型的工程副作用:当你开始认真梳理一条链路,项目里原本被忽略的边角错误也会一起浮出来。
我在跑检查的时候,先后碰到了两个问题。
一个是 LightDarkSwitch 在 Astro 里的类型推断异常,导致 client:only="svelte" 这类写法在导航栏里报错。最后回头看,问题并不是导航栏本身,而是组件内部状态写法和项目其余部分的预期并不一致。
另一个是归档页类型定义过窄。内容 schema 允许分类是 null,但归档面板里却把它写成了更严格的 string | undefined,结果父组件一把真实数据传进去,类型系统立刻就不认了。
这类问题的有趣之处在于,它们平时并不一定会把页面直接搞挂,所以很容易长期留在那里。但一旦你开始认真做结构性改造,类型系统就会像放大镜一样把这些不一致都照出来。
说到底,这不是“改着改着改出新 bug”,而是“原来已有的问题终于被看见了”。
我开始更喜欢这种“解耦之后再推进”的感觉
这一晚做的很多事,表面上都不算大功能。
第一篇是把部署链路理顺。 第二篇是把文章组织和 URL 规则理顺。
它们的共同点是,都不属于那种用户一眼就能看到的“新东西”。页面不会因为这些改动看起来更炫,功能列表里也不会多出什么特别夸张的能力。
但它们会让后续每一步都更顺。
部署从 root 拆出来之后,我知道以后发布边界在哪里。 URL 从目录里拆出来之后,我知道以后改内容结构时哪些地方可以动,哪些地方最好别动。
这种感觉很像把桌面先收拾干净,再开始干活。真正提升效率的,常常不是那一瞬间多做了什么,而是后面每一步都少了很多不必要的摩擦。
今天的第二篇,就记这个系统终于开始像系统了
如果说第一篇更像“站点上线前的工程收尾”,那这一篇大概就是“内容系统终于开始成型”的记录。
文章目录、URL、路由、RSS、归档、类型定义,这些零碎的东西原本各管各的。现在它们终于围绕一个更明确的规则站到了一起。
以后我写文章时,不需要再手动想 slug,不需要再为一天写两篇而改命名策略,也不需要担心目录一改,外部链接就会跟着变。
这其实不是一次很张扬的升级,但它对一个准备长期写下去的博客来说,刚好是那种足够基础、也足够值得尽早做的事。
系统感这种东西,很多时候不是靠增加复杂度得来的,而是靠把本来就不该耦合在一起的东西拆开。
今天做的,就是这样一次拆分。