如果你正在看这篇文章,说明你已经站在了这个网站的成品里。这篇文章复盘它从零到上线的全过程:怎么选型、怎么组织内容、怎么把一个英文模板改造成全中文的个人站,以及上线前踩过的那些坑。

选型:静态站 + 模板二开
我的需求很明确:写文章、挂自己写的小工具、放点截图相册,不要动态后端、不要数据库,部署简单、国内访问快。答案自然落在静态站点生成器上。
最终选择 Astro 6 做底层,Tailwind 4 写样式,在一个叫 Devosfera 的开源主题(AstroPaper 的深度定制分支)基础上二次开发。选它的原因有三:
- 内容集合(Content Collections)模型:文章、相册、工具都是带 schema 校验的 Markdown 文件,写错 frontmatter 构建直接报错,不会静默出问题;
- 零默认客户端 JS:页面是构建期渲染的 HTML,只有主题切换、搜索弹窗这类交互有少量脚本,首屏快;
- 生态齐全:Pagefind 静态搜索、Satori 动态生成分享图(OG Image)、sitemap、RSS 都是现成集成。
内容模型:三个集合,一条时间线
这个站有三类内容,分别对应 src/data/ 下的三个目录,schema 定义在 content.config.ts:
blog/—— 文章(就是你现在读的这种);galleries/—— 相册,一个文件夹一册,index.md写元数据,图片放同目录自动聚合;tools/—— 工具页,比文章多demoUrl、repoUrl、status几个字段。
tools 集合是我在原模板上新增的:定义 schema、写 ToolCard 组件、加 /tool 路由、导航栏补一个入口,半天就能完成。新增一篇内容永远等于新增一个 Markdown 文件,这是我最喜欢静态站的地方——写作即数据。
时间线页(/timeline)是全站内容的聚合视图。原模板只聚合文章和相册,工具被漏在外面——直到某天我打开时间线,看到一枚孤零零的徽标「0 años」。

这行西班牙语是模板作者的遗产(Devosfera 是西语项目),汉化时被漏掉了;月份名数组也是整套的 Enero、Febrero。修复很简单:时间线的数据源从两个集合扩到三个,顺手把徽标改成「条内容」「年」、月份改成中文。于是工具卡片(标题前带归档小图标的那张)就和文章、相册排进了同一条时间线,样式完全一致。
视觉与中文化
模板是英文(夹杂西语)项目,全站文案中文化是细活:页面标题、面包屑、404、搜索弹窗、页脚……逐个组件过。字体是重头戏——国内访问 Google Fonts 不现实,全部改为自托管:
- 标题:阿里妈妈方圆体(可变字体,7.4MB 一个文件覆盖全部字重);
- 强调/楷体角色:得意黑 Smiley Sans;
- 代码与标签:Fira Code Medium + MiSans 分片加载。
踩过一个 Tailwind 4 的坑:它不处理 CSS 里的 @import url(),MiSans 必须改用 <link> 标签引入,否则字体静默消失。这类问题构建不会报错,只能靠肉眼逐页验收。

构建、搜索与部署
构建命令一行:astro check(类型检查)→ astro build(渲染 40 多个静态页)→ pagefind(为全站建中文搜索索引,你现在在搜索框里能搜到这篇文章就是它的功劳)。
部署走「本地构建 + 推送产物」:构建产物打包上传服务器,nginx 直接托管静态目录;/tool/yiban-auto-sign/demo/ 路径反代到本机一个 Flask 服务做在线演示。每次部署前后有 prev/old 双备份轮换,出问题一条命令回滚。域名备案、TLS 证书、安全响应头这些上线前的功课,我写在下一篇《给网站做一次全链路加固》里。
小结
回顾整个过程,搭一个博客站的难度不在写代码,而在做决定:选静态还是动态、自托管还是 CDN、模板二开还是从零写。我的答案是——内容模型选最严格的(schema 校验),样式交给现成设计系统,部署链路越短越好,把省下的精力全部留给写作本身。
这篇文章本身也是范例:它就是一个放在 src/data/blog/ 里的 Markdown 文件。