要的东西很简单:写 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 加一条记录:

类型名称内容代理
CNAMEblogqzgjx-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 这套组合,把「自己搭」的成本压到了大约两小时。