跳过正文

心动?同款博客搭建指南奉上!

asm2apex
作者
asm2apex
目录

博文概览
#

博文概览

这篇文章写给两种人:

  1. 想在 macOS 上把 Hugo 搭起来的人
  2. 已经搭起来了,但看着自己的站点,总觉得还差点“网感”的人

我会从「macOS 安装 Hugo」讲到「推到 Git 私有仓库」再到「Vercel 部署上线」,最后把我到目前为止做过的配置、功能、样式改动一口气盘出来。没有玄学,没有“以后也许用得上”的过度设计,只有能跑、好改、可复制。

0. 目标与路线图
#

目标就三个:

  • 本地能跑:hugo server 一开,页面正常渲染
  • 版本可控:Git 管起来,别把构建产物塞进仓库恶心未来的自己
  • 上线省心:Vercel 自动构建 + 自动部署

路线图:

  1. macOS 安装 Hugo
  2. 初始化站点 + 选主题(Blowfish)
  3. 配置与内容结构落地
  4. 推送到 Git 私有仓库
  5. Vercel 部署
  6. 后续:功能和外观的“人模人样化”

1. macOS 安装 Hugo:别搞复杂
#

我用 Homebrew,原因很朴素:少折腾。

brew install hugo
hugo version

能输出版本号就行。别在这一步研究“最佳安装姿势”,你要的是博客,不是安装教程写作大赛。

2. 初始化站点:先跑起来再说美
#

在一个空目录里:

hugo new site blog
cd blog

然后先确认最小闭环:

hugo server

如果这里就报错,先别继续加戏,先把基础的配置问题解决。

3. 主题 Blowfish:选个能用的,别自虐
#

我选择 Blowfish,原因也很现实:成品度高,配置项够用,视觉不丑。

主题接入完成后,最关键的一步是:确保 Hugo 知道你在用这个主题

我这里的站点配置在 config/_default/hugo.toml,核心就是:

theme = "blowfish"

这行如果没生效,你会得到经典名场面:Page not Found,并且日志疯狂提示找不到 layout。不是你的页面不见了,是 Hugo 根本没法渲染。

4. 配置落地:中文、菜单、列表、背景
#

4.1 默认中文
#

我把默认语言切到 zh-cn,配置文件在:

  • config/_default/hugo.toml
  • config/_default/languages.zh-cn.toml

你可以理解为:站点“默认说中文”,而不是“在中文里夹英文配置”。

4.2 菜单汉化
#

菜单在:

  • config/_default/menus.zh-cn.toml

常用的就是文章 / 分类 / 标签,把注释解开,改名就完事。别整“菜单生成器”,你不是在写后台管理系统。

4.3 文章列表宫格(卡片视图)
#

列表页(比如 /posts/)想要像示例站那样宫格卡片,就改:

  • config/_default/params.toml[list]

核心就是开启卡片视图:

  • showCards = true
  • cardView = true

4.4 首页背景与文章页背景:别把首页配置当文章配置
#

这点我自己踩过坑:你在 [homepage] 里配的 homepageImage 只影响首页,不会自动传到文章页。

文章页要背景(Hero),需要在 [article] 里打开:

  • showHero = true
  • heroStyle = "background"

然后背景图来源有两条路:

  1. 每篇文章单独放 background* / cover* 这种命名的图片在文章目录里(page bundle)
  2. 或者全站默认设置 defaultBackgroundImage

一句话:想要背景就显式开 hero,不要指望它“继承”。

5. 内容与目录:我选了“可维护”的结构
#

我现在的文章路径是按日期分层的,比如:

content/posts/2026/01/27/blog/index.md

这种结构的优点:文件系统一眼能看懂,迁移也方便。缺点也很明显:目录层级深,但我宁愿深一点,也不想把所有文章都堆在一个目录里然后靠搜索活着。

6. 评论区:Giscus,省钱但不省心
#

我用 Giscus,基于 GitHub Discussions。优点:免费、干净。缺点:评论的人得有 GitHub 账号。

Blowfish 的机制很直白:你提供一个 partial,它就渲染。

  • 评论 partial:layouts/partials/comments.html
  • 开关:config/_default/params.toml[article] showComments = true

6.1 日/夜模式同步
#

Giscus 默认不会自动跟主题切换同步。我这里的做法是:

  • 加载时用当前主题选择 data-theme
  • 监听 htmldark class 变化,发 postMessage 让 giscus 切主题

这不是“炫技”,是因为不做就真的不好用。

7. 阅读时间与阅读数:一个免费,一个看你钱包
#

7.1 阅读时间(X 分钟)
#

这是 Hugo 自带的 .ReadingTime。但中文文章如果不启用 CJK 计数,阅读时间会非常离谱或者为 0。

我这里建议在 config/_default/hugo.toml 开:

hasCJKLanguage = true

7.2 阅读数(浏览量)
#

Blowfish 的“阅读数”是用 Firebase Firestore 统计的:能用,但不是 Hugo 的原生能力。

说人话:你要不想花钱,就别上这个;要上,就把 Firebase 配置、匿名登录和 Firestore 规则弄好。

8. 外观与细节:从“能看”到“像个站”
#

8.1 左上角 Logo:日间一张,夜间一张
#

主题默认只支持一个 logo。我不想在夜间模式看“反差刺客”,所以我做了一个小覆盖:

  • layouts/partials/header/basic.html

支持:

  • logo = "img/blog-day.png"
  • logoDark = "img/blog-night.png"

图片放 assets/img/,路径用相对路径就行。

8.2 浏览器标签页图标(favicon)
#

Hugo 的静态文件覆盖规则很明确:你项目里的 static/ 会覆盖主题的 static/

但问题是:浏览器不只认 favicon-32x32.png,还认 favicon.icosite.webmanifest 等一堆东西。你只替换两张 PNG,等于只改了“冰山一角”,剩下的浏览器还是会去拿主题的。

所以我把整套 favicon 放到了 static/,让它们同名覆盖主题资源。

8.3 分类/标签/文章列表页标题中文化(别指望它自动懂中文)
#

我一开始在 /categories/ 看到一个大大的 Categories,这不是主题挑衅你,是 Hugo 的默认行为:taxonomy 的标题就是把 categories 首字母大写一下。

想改很简单,给这些页面加 _index.md,用 title 覆盖默认标题:

  • content/categories/_index.md -> title = "分类"
  • content/tags/_index.md -> title = "标签"
  • content/posts/_index.md -> title = "文章"

注意:description 依然只进 <meta>,页面正文默认不显示(这是主题模板的选择,不是你写错了)。

8.4 分类/标签页也要背景(taxonomy/term 的开关和 list 不是一回事)
#

/posts/ 有背景,不代表 /categories//tags/ 也会有,因为它们走的是不同的页面类型。

我这里把这两类也显式打开了 hero:

  • config/_default/params.toml[taxonomy] showHero = true
  • config/_default/params.toml[term] showHero = true

同样配 heroStyle = "background",背景图就会跟文章页/列表页用同一套规则(优先页面资源,其次 defaultBackgroundImage)。

9. Git 私有仓库:别把垃圾推上去
#

我加了 .gitignore,至少要忽略这些:

  • public/(构建产物)
  • resources/(Hugo 缓存)
  • .hugo_build.lock

不然你每次构建都能把仓库搞脏,最后你会开始痛恨“曾经的自己”。

10. Vercel 部署:能自动化就别手动
#

思路很简单:

  • 代码推到 Git
  • Vercel 连接仓库
  • 设定构建命令:hugo --minify
  • 输出目录:public

然后你就能享受“我一 push,它就自动上线”的快乐。

11. 我踩过的坑(供你避雷)
#

11.1 本地能启动但全站 404
#

根因:主题没启用(theme = "blowfish" 没生效),导致 Hugo 找不到布局模板。

11.2 文章“写了但看不到”
#

根因之一:文章时间在未来,且 buildFuture = false
根因之二:首页不展示 recent(homepage.showRecent = false),所以你以为“文章没了”,其实只是“首页不列出来”。

11.3 右侧目录不显示(别怪主题,先怪自己)
#

目录(TOC)出现需要两个条件同时满足:

  1. 开关打开:config/_default/params.toml[article] showTableOfContents = true
  2. 页面真的有“可生成 TOC 的标题”:也就是至少有 ## / ### 这种层级标题

另外 config/_default/markup.toml[tableOfContents] startLevel = 2,意味着 # 一级标题 不会进目录,这是正常的。

11.4 分类/标签“有了但我在目录页没看到文章”
#

/categories//tags/ 页只列“有哪些分类/标签”,不是文章列表。

你要点进去看:

  • 分类:/categories/教程/
  • 标签:/tags/hugo/(URL 会被自动转成小写/连字符,这是正常的)

如果你刚加完分类标签但页面没刷新,别猜:重启 hugo server,或者直接用 hugo server -D --disableFastRender

12. 结尾:我还会继续折腾,但不会过度设计
#

博客就是博客,别把它写成“可扩展内容平台”。
想加功能就加,但每次都问自己一句:这玩意儿现在真的需要吗?