要的东西很简单:写 Markdown,git push(或者说一句命令)之后网页就变,不加服务器,不装数据库,最好还免费。
Hugo + Cloudflare Pages 正好是这条路径里最短的一条。
为什么是 Hugo
静态站点生成器很多,Hugo 的优势只有一个,但足够致命:快。
二十篇文章的站点,构建时间通常在 100 毫秒级别。这意味着本地改完样式,hugo server 一刷新就能看到结果,改版式的体验接近直接写 CSS。Hexo 在这件事上会让你等,Astro 更慢一些(但它能做的事也更多)。
代价是 Go template 语法不如 JSX 直观。不过博客的模板就那么几个,一次性写完之后基本不用再碰。
目录结构
最小可用的结构大概是这样:
blog/
├── hugo.yaml # 站点配置
├── content/
│ ├── about.md
│ └── posts/
│ └── hello.md
├── layouts/ # 模板
│ ├── _default/
│ │ ├── baseof.html
│ │ ├── single.html
│ │ └── list.html
│ └── partials/
├── assets/ # 需要 pipeline 处理的资源
│ ├── css/main.css
│ └── js/app.js
└── static/ # 原样拷到根目录
└── _headers
assets/ 和 static/ 的区别容易搞混:前者要被 Hugo 处理(压缩、指纹、SCSS 编译),后者只是原封不动复制过去。
资源管线
CSS 和 JS 走一遍 minify + fingerprint,文件名会带上内容哈希:
{{ $css := resources.Get "css/main.css" | minify | fingerprint }}
<link rel="stylesheet" href="{{ $css.RelPermalink }}"
integrity="{{ $css.Data.Integrity }}">
这一步值得做。文件名带哈希之后,就可以放心给静态资源设一年缓存——内容一变,URL 就变,浏览器必然拉新文件。省掉了「让用户强刷」的所有沟通成本。
部署
Cloudflare Pages 支持两种模式:连 Git 仓库自动构建,或者本地构建完直接上传(Direct Upload)。
我选后者,原因是构建环境完全可控。Hugo 的版本、镜像源、环境变量都在自己手上,不会出现「本地好好的,云端构建失败」。
hugo --minify --gc
wrangler pages deploy public --project-name=qzgjx-blog --branch=main
第一次会因为项目不存在而失败,先去控制台建一个同名项目,或者用 API 建:
curl -X POST "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/pages/projects" \
-H "Authorization: Bearer $CF_TOKEN" \
-H "Content-Type: application/json" \
-d '{"name":"qzgjx-blog","production_branch":"main"}'
绑自定义域名
在 Pages 项目的 Custom domains 里加 blog.qzgjx.top,然后去 DNS 加一条记录:
| 类型 | 名称 | 内容 | 代理 |
|---|---|---|---|
| CNAME | blog | qzgjx-blog.pages.dev | 已代理(橙色云) |
因为域名本身就在 Cloudflare 托管,这一步几乎是瞬间生效的,证书也会自动签发。如果域名在别家注册商,记得把 NS 切到 Cloudflare,否则拿不到自动证书。
几个坑
1. 二级目录的 _headers 不生效。 必须放在根目录,而且路径要写全,比如 /css/*。
2. 自定义域名的缓存比 pages.dev 长。 *.pages.dev 每次部署立刻更新,绑定的自定义域名可能还返回旧内容,响应头里 cf-cache-status: HIT 就是证据。等十几分钟,别急着重建项目。
3. baseURL 一定要写成最终域名。 写错的话 RSS 和 sitemap 里的链接会全部指向错误地址,而且本地看不出来——因为 hugo server 用的是它自己的地址。
值得吗
如果一年只写三篇,用 Notion 或者公众号更省事。
但只要你想控制排版、想加一行自己的脚本、想让页面在 300ms 内打开,自己搭就是唯一的选择。而 Hugo + Pages 这套组合,把「自己搭」的成本压到了大约两小时。