上个月有个同事跟我说,他花了两天时间搭了个 WordPress 博客,结果第三天就在折腾插件兼容性和服务器内存,第四天直接把博客删了。我给他推荐了 Hugo,他半天时间把博客重新搭好,还写完了第一篇文章。这件事让我特别想聊聊 Hugo——不是因为 WordPress 不好,而是对大多数只是想写点东西的人来说,Hugo 的“快”几乎是降维打击。
Hugo 是目前最流行的静态站点生成器之一,长期霸榜 GitHub 星标前列。它用 Go 语言编写,号称“全世界最快的建站工具”,单个二进制文件就能跑,不依赖 Node.js、PHP 或数据库。如果你需要一个博客、个人作品集、产品文档站,或者公司技术文档中心,Hugo 几乎是最省心的选择。这篇东西不是什么官方文档翻译,就是我自己从零搭建、写了一百多篇文章之后的实操总结,从选型到部署一条龙讲清楚,新手照着做就行,老手可以重点看后面的排查技巧。
1. 为什么我最终选了 Hugo——静态博客选型那点事
1.1 静态站点生成器对比:Hugo、Hexo、Jekyll
先聊选型,这是动手之前最重要的决定。市面上主流的静态站点生成器,算来算去就三座大山:Hugo(Go)、Hexo(Node.js)、Jekyll(Ruby)。
说几个数据你就明白差距了。我拿一个大约 300 篇文章、2000 张图片的站点做构建测试:Jekyll 冷构建大约需要 90 秒,Hexo 大约 50 秒,Hugo 第一次构建花了不到 3 秒,之后都是毫秒级。这个差距在本地预览时体验尤其明显——Jekyll 改一篇文章要等整个站点重新编译,Hugo 几乎是你保存文件的同时页面就刷新了。写文章本来就是碎片化的思路,等构建时间会严重影响写作节奏。
| 对比项 | Hugo | Hexo | Jekyll |
|---|---|---|---|
| 构建速度 | 毫秒级(3000+页面/秒) | 秒级 | 秒级 |
| 环境依赖 | 单二进制,无依赖 | Node.js | Ruby/Gem |
| 主题生态 | 丰富,专业感强 | 丰富,偏前端风格 | 一般 |
| 学习曲线 | 中等(模板语法稍复杂) | 较低 | 中等 |
| 适合场景 | 博客、文档站、企业站 | 个人博客 | GitHub Pages 默认支持的站 |
从环境依赖看,Jekyll 需要 Ruby 环境,Windows 用户装 Ruby 本身就是个劝退现场;Hexo 需要 Node.js,虽然现在前端同学都有 Node,但对纯写作者来说还是多一道门槛。Hugo 在这方面做得很绝——官方发布页直接提供各平台的二进制文件,下载解压就是完整工具,没有依赖地狱。我到现在都记得第一次用 hugo version 命令看到版本号弹出来时的那个爽快感。
另外说一句,GitHub Pages 原生支持 Jekyll,所以很多人当初从 Jekyll 入坑。但 Pages 有插件限制,很多 Jekyll 插件根本跑不了。Hugo 虽然原生不支持,但用 GitHub Actions 部署也就十分钟的事情,后面我会详细讲。
1.2 Hugo 的核心优势:速度只是表象
Hugo 真正的核心优势不止是构建速度快。首先是部署的极度简化——它生成的是纯静态 HTML 文件,你把它丢到任何 Nginx、S3 对象存储、CDN、GitHub Pages 上都能跑,完全不需要服务器端动态处理。这就意味着你几乎不用担心黑客入侵、服务器宕机、数据库损坏这些问题,除了域名续费,每年维护成本趋近于零。
其次是 Hugo 对内容的组织方式非常灵活。它支持多语言站点、多层级内容结构、自定义分类法、内容引用和短代码。举个例子,我博客里有个“读书笔记”板块,每本书的文章需要同时按“书名”、“主题”、“阅读年份”三个维度归类,Hugo 的 taxonomies(分类法)机制可以轻松实现,在 Hexo 里就得写插件或者硬编码了。
Hugo 的短代码(Shortcodes)也是个被低估的功能。你在 Markdown 里写文章,但需要嵌入一个响应式视频播放器、一个带全屏的图片画廊、一个可折叠的提示框,原生 Markdown 做不到。Hugo 允许你把这些功能封装成短代码,写文章时一行调用即可。后面我会展示一个实际例子。
还有一个点,Hugo 没有后台,没有数据库,写作完全本地化。只要你的 Markdown 文件还在,换任何一台电脑,克隆一下 Git 仓库,整个博客就完整回来了。我用 WordPress 那会儿,最怕的就是备份数据库,有一次误删了一个数据表差点把两年的文章全弄丢。现在我的整个博客就是一个 Git 仓库,回滚、备份、协作全靠 Git,这是一种让人上瘾的安全感。
1.3 Hugo 的短板,提前告诉你
说完了好话,也得讲讲它的短板,免得你抱着错误预期入坑。Hugo 的模板语言是 Go 的 html/template,和常见的 Jinja2、EJS 风格不太一样,刚开始写自定义模板会有点别扭。Go 模板的变量解析、管道语法、上下文切换,初次接触确实需要一点时间适应。
主题定制方面,如果你想要一个完全定制化的设计,Hugo 需要理解它特有的 Blocks(模板块)机制。不像 Hexo 那种简单的子模板覆盖,Hugo 的 Blocks 设计更强大,但理解起来需要时间。从另一个角度看,正因为它灵活,你几乎能实现任何布局,网上很多优秀公司都用 Hugo 做站点,性能和可维护性都非常好。
所以我的建议是:如果只是搭个博客,找一套成熟主题先用起来,不要一上来就陷入自定义模板的兔子洞。写文章才是你的主业,博客系统的美化应该排后。
2. 环境准备与站点初始化——别急着装主题,先把地基打牢
2.1 安装 Hugo 的三种主流方式
Hugo 安装方式根据你的操作系统和个人偏好有不同选择。我自己用的 macOS,同事用 Windows,还有跑 Linux 服务器的,三种环境我都折腾过,分别说说。
macOS 用户最简单的方式是 Homebrew:
brew install hugo这里我要特别强调一个坑:Homebrew 默认安装的是 Hugo 的 Standard 版本,但很多主题(尤其是用 SCSS 预处理的主题)要求 Extended 版本。两个版本的区别是 Extended 多了 Sass/SCSS 编译能力。我第一次用某个主题时,构建一直报错error: SCSS transpilation requires Hugo Extended,折腾了半天才发现是版本问题。解决办法:
brew install hugo-extended # 或者如果你已经装了普通版 brew uninstall hugo brew install hugo-extendedWindows 用户推荐用 Scoop:
scoop install hugo-extended如果没有 Scoop,去 Hugo 官方 GitHub Releases 页面下载hugo_extended_windows-amd64.zip,解压后把 hugo.exe 所在目录添加到 PATH 环境变量,同样能解决问题。
Linux 用户看发行版。Debian/Ubuntu 用 Snap 比较方便:
sudo snap install hugo但 Snap 版更新可能滞后,想要最新版还是建议去 Releases 下载二进制。装好后用hugo version验证:
$ hugo version hugo v0.125.7+extended darwin/amd64 BuildDate=2024-06-04T16:13:09Z看到输出中有+extended就说明安装的是扩展版。版本号 0.125.7 是我当时用的版本,Hugo 迭代速度极快,你装到的版本可能更新,没关系,只要语法兼容,文章和主题都能正常处理。
2.2 用一条命令初始化站点骨架
装好 Hugo 之后,打开终端,进入你想创建项目的目录,执行:
hugo new site myblog cd myblog这一条命令会生成一个完整的目录骨架。我第一次看到这堆目录时其实有点懵,但摸清楚每个目录的作用之后,整个 Hugo 的设计逻辑就通了:
myblog/ ├── archetypes/ # 内容模板(新文章默认生成的 front matter) ├── assets/ # 被 Hugo 处理的资源(SCSS、图片、JS) ├── content/ # 你的所有 Markdown 文章都在这里 ├── data/ # 配置文件数据(可被模板读取) ├── layouts/ # 自定义模板(覆盖主题的模板) ├── static/ # 静态文件(图片、PDF、favicon 等,会原样复制到输出目录) ├── themes/ # 下载的主题放在这里 ├── public/ # hugo 命令生成的最终静态站点文件 └── hugo.toml # 站点的主配置文件这七个目录中,你日常会频繁打交道的其实只有 content、static 和 archetypes。layouts 偶尔改主题才会用,assets 和 data 属于进阶功能,public 目录是生成的,不用碰也别手动编辑——下次构建会被覆盖。
这里我强烈建议把站点目录初始化成一个 Git 仓库:
git init git add . git commit -m "init site"为什么要从一开始就做这件事?因为主题、配置、文章都需要版本管理,后续部署到 GitHub Pages 或者 Netlify 都需要 Git 仓库。我见过有人等到部署时才想起 Git,结果折腾半天才发现没有仓库,建了仓库又把所有文件一股脑全提交,历史混乱得没法看。从一开始就提交,后面每改一点都可以安心回滚。
2.3 配置文件的关键设置:hugo.toml 与语言选择
Hugo 默认生成的是hugo.toml(TOML 格式),但很多主题的示例配置是 YAML 格式。我个人偏好 YAML,因为它更简洁、缩进结构更清晰,但如果你习惯 TOML,完全可以用默认的。其实三种格式(TOML、YAML、JSON)Hugo 都支持,选哪种不重要,关键是全程一致,不要混用。
先看最基本的配置。打开hugo.toml,至少需要设置这几个字段:
baseURL = 'https://yourname.github.io/' languageCode = 'zh-cn' title = '我的博客'baseURL是你最终部署的域名,这个必须一开始就设对。本地预览时你可以随便填,但部署到线上后,站点里所有链接、sitemap、RSS 都会基于这个 baseURL 生成。如果填错了,部署后你会看到样式加载不出来、文章链接全部 404 的诡异现象——其实不是文件丢了,而是路径拼错了。
languageCode填zh-cn可以让浏览器正确识别页面语言,对 SEO 也有帮助。title会出现在浏览器标签页和站点头部。
这个文件后续还会不断添加新配置,比如主题参数、导航菜单、分类法配置等。我的建议是,每次加新配置项,都先跑一遍hugo server确认没报错,再提交 Git。Hugo 的配置错误提示其实挺人性化的,会明确指出哪一行有问题,不要怕试错。
3. 主题安装与核心配置——把博客调成顺手的样子
3.1 如何挑选主题,我的四个筛选标准
Hugo 的主题生态虽然没有某些前端框架那么庞大,但好用的也足够你挑花眼。官方主题站 themes.gohugo.io 上有几百套主题,我筛选主题时只看四个标准:
一看是否持续维护。点进主题的 GitHub 仓库,看最近 commit 日期。半年以上没更新的基本可以直接排除,因为 Hugo 本身迭代快,不跟进的主题往往会有兼容问题。
二看是否支持中文。很多国外主题的字体设置对中文很不友好,中文字体没配置好,页面显示会很丑。另外主题的示例站点有没有中文章节,能侧面反映作者是否重视中文用户。
三看结构是否清晰。下载后打开主题的 layouts 目录,看文件组织是否规整。主题未来的扩展空间取决于模板结构的规范性。
四看示例站点是否好看。这个很主观,但主题的 exampleSite 就是你未来站点的雏形,如果示例站点都丑,自己改出美观的概率也不大。
我最终选择的是 Toha 主题,因为它干净、专业,对中文支持极好,而且内置了 SEO 和暗色模式功能。不过下面讲的操作流程适用于绝大多数主题,关键是逻辑,具体参数以你选择的主题文档为准。
3.2 下载主题并配置示例内容
选定主题后,在themes目录下克隆它:
git clone https://github.com/gohugoio/hugo-theme-toga.git themes/toha很多主题的仓库里有一个exampleSite目录。这个目录包含主题作者推荐的完整内容结构、截图和配置示例。最佳实践是把里面的内容文件复制到你的站点根目录,而不是从头开始写:
cp -r themes/toha/exampleSite/content/* ./content/ cp -r themes/toha/exampleSite/static/* ./static/ cp -r themes/toha/exampleSite/assets/* ./assets/ cp -r themes/toha/exampleSite/config.yaml ./hugo.yaml复制完,把主题名称配置到主配置文件:
theme: toha然后启动本地预览:
hugo server -D这里-D(Draft 的缩写)很重要,意思是把标记为草稿的文章也渲染出来。如果你不加这个参数,草稿状态的 Markdown 文章在本地预览里是看不到的。我第一次跑 Hugo 时没加 -D,博客首页空白一片,当时还以为是主题坏了,其实是草稿不渲染的原因。
浏览器打开http://localhost:1313,如果看到站点正常显示,说明配置成功。这时候你复制过来的 exampleSite 内容会展示出来,包括文章示例、关于页面、项目展示等,它们的作用是让你确认主题跑起来了,后续要慢慢替换成你自己的内容。
3.3 核心配置详解:baseURL、菜单、分类法与页脚
主题跑起来之后,接下来就是按照自己的需求调整配置。最重要的几个部分我逐一说明。
baseURL 必须第一时间改成你的正式域名。如果你还没确定域名,GitHub Pages 的固定域名格式是https://你的用户名.github.io/,先填这个,后面绑定自定义域名再改回来即可。
导航菜单配置。在 Hugo 中,顶部导航菜单项都定义在主配置文件的menu字段里。以 Toha 主题为例:
menu: main: - name: "首页" url: "/" weight: 1 - name: "博客" url: "/posts" weight: 2 - name: "关于" url: "/about" weight: 3weight字段决定菜单项的排列顺序,数值越小越靠左。注意,菜单项的 url 必须与实际内容路径对应,比如 博客 对应 content/posts 目录,关于对应 content/about.md。对不上就会出现点击菜单跳转到 404 的情况,排查时优先检查这个对应关系。
分类法(Taxonomies)配置。Hugo 默认把 tags 和 categories 作为两套分类法,这个机制大有用处。我在 config 里自定义了一套:
taxonomies: tag: tags category: categories series: series这样每篇文章可以同时归属于标签、分类和系列,适合写教程时把同系列文章串起来。配置好之后,在文章 Front Matter 里只要写series: Hugo 教程,站点就会自动生成一个 series 存档页,里面能按时间倒序列出所有属于这个系列的文章。这个功能对长内容创作者来说太实用了。
页脚(Footer)配置。大多数主题的页脚在params.footer字段下,可以设置版权文案、备案号(如果你在中国大陆部署)、社交链接等。我的页脚放了一段简单的文字:© 2024 My Blog · Powered by Hugo & Toha,既表明版权又给技术栈做个小推广。
4. 内容写作与本地调试——博客的真正日常
4.1 Front Matter 详解:每篇文章的“身份证”
当你创建一篇新文章时,Hugo 会根据archetypes目录里的模板文件生成带默认 Front Matter 的 Markdown 文件。执行:
hugo new posts/my-first-post.md生成的文件开头会有这样一段:
--- title: "My First Post" date: 2024-06-10T10:00:00+08:00 draft: true tags: [] categories: [] ---这段 YAML 格式的元数据就是 Front Matter。它是 Hugo 内容系统的心脏,决定文章如何被渲染、归档、匹配。几个关键字段:
title是文章标题,会在文章页、列表页、浏览器标签页、SEO 元信息中显示。Hugo 默认会把文件名转成标题,如果文件名是my-first-post.md,标题默认为My First Post,你要手动改成真正的中文标题。
date字段决定文章的时间戳。这个字段有个坑:如果你用hugo new创建文章,它会自动填入当前时间;但如果你手动创建 Markdown 文件时忘了这个字段,Hugo 会回退到文件的 Git 提交时间或系统文件修改时间,这会导致文章日期显示不对。所以建议每篇文章都显式写上 date。
draft字段如果是true,文章不会被正式构建。新文章默认都是true,发布前记得改掉,否则部署后文章不会出现。这个众人都知道的“坑”,其实是 Hugo 刻意设计的安全机制——防止你不小心把未完成的草稿发布出去。
此外,常用字段还有summary(文章摘要,不写则自动取正文前 70 个字符)、tags/categories(标签分类)、aliases(旧文章改路径后的重定向)、weight(列表页置顶排序权重)。写作时养成好习惯,先把这些字段写清楚,后面管理起来会非常顺手。
4.2 用 Markdown 写作并插入“短代码”
Front Matter 下面的正文就是纯 Markdown。Hugo 对 Markdown 的渲染使用内置的 Goldmark 引擎,完全支持 CommonMark 标准和 GFM(GitHub Flavored Markdown),也就是说你平时在 GitHub 上怎么写文章的语法,在 Hugo 里都适用。
关于图片处理,我踩过不少坑,最后总结出一套稳妥方案:不要把图片直接丢到文章旁边引相对路径,而是放在两个地方:一是全局共享的图片(logo、favicon)放static/images/,二是单篇文章相关的图片放在和文章同名的目录下。
举例子来说,不要用hugo new posts/apache-tuning.md,而是用:
hugo new posts/apache-tuning/index.md然后把文章相关的截图都放在content/posts/apache-tuning/目录下,文章内用:
这样做的好处是文章和它的图片在文件系统里是一个整体,移动、复制、备份都非常方便,不会出现图片路径断裂的问题。
短代码是 Hugo 写作的高级功能。比如我想在文章里嵌入 GitHub 代码片段列表,用原生 Markdown 很难搞定,但 Hugo 里可以直接写:
{{< github repo="yourname/yourrepo" >}}再比如,我想插入一个带标题的图片,可以写:
{{< figure src="/images/architecture.png" title="系统架构图" width="800" >}}这些短代码主题一般都会自带一些,你也可以自己写。原理上短代码就是一个布局模板,放layouts/shortcodes/目录下,函数逻辑还是 Go 模板语法,进阶用户可以去研究,新手先用主题自带的就好。
4.3 本地调试:Hugo Server 的隐藏功能
hugo server是本地调试的核心命令,但它的启动参数很有讲究。我平时最常用的组合:
hugo server -D --port 8080 --navigateToChanged各个参数的作用:-D渲染草稿文章;--port 8080自定义端口,默认 1313,但如果有多个项目同时预览,端口必须手动改避免冲突;--navigateToChanged是 Hugo 3.0 后我最爱的参数,当 Markdown 文件保存后,浏览器自动刷新并滚动到修改位置附近,写长文时定位上下文特别方便。
如果你改了配置文件,不需要重启 Hugo server,它监听配置文件变化并自动重载。不过改了 config 的某些深层参数,偶尔会有缓存问题,导致无法立刻看到效果,这时候重启一轮 server 大概率能解决——我的经验是,99% 的“改了没反应”靠重启都能解决。
本地调试时还有个实用技巧:按 Ctrl+C 停止服务,然后执行:
hugo --gc --minify--gc会清理构建缓存,--minify会压缩 HTML。跑完后生成最终的public目录,这个目录里的文件就是将来要部署的最终产物。你可以先python3 -m http.server 8080 -d public预览成品,确保正式构建没有问题。
5. 部署上线与常见问题排查——让它被全世界看到
5.1 GitHub Pages 部署:从零到有,两条路都走一遍
本地调试跑通后,接下来就是部署。GitHub Pages 是最简单、免费的部署方案,新手推荐从这里入手。
首先,把之前的本地 Git 仓库推到 GitHub 上。仓库名如果是你的用户名.github.io,GitHub 会自动识别并启用 Pages。
第一种方式:GitHub Actions 部署(推荐)。
在仓库根目录创建.github/workflows/deploy.yml:
name: Deploy Hugo site to Pages on: push: branches: - main permissions: contents: read pages: write id-token: write jobs: build: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 - name: Setup Hugo uses: peaceiris/actions-hugo@v3 with: hugo-version: '0.125.7' extended: true - name: Build run: hugo --minify - name: Deploy uses: peaceiris/actions-gh-pages@v4 with: github_token: ${{ secrets.GITHUB_TOKEN }} publish_dir: ./public每次你把代码推送到 main 分支,GitHub Actions 就会自动执行:拉取代码、安装指定版本 Hugo、执行hugo --minify构建、部署public目录到 Pages。整个流程完全自动化,之后只管写文章推送就行。
注意,extended: true必须开启,不然 SCSS 主题就会在 CI 上构建失败,这个坑我把同事坑过两回。hugo-version 填你自己的版本号,建议不要用latest,因为 Hugo 大版本升级偶尔会有破坏性变更,锁定版本可以避免“昨天还能跑,今天突然坏了”的尴尬。
第二种方式:推送到 gh-pages 分支(简单粗暴)。把public目录单独推送到 gh-pages 分支,可以参考:
hugo --minify git subtree push --prefix public origin gh-pages两种方式我推荐第一种,因为 Actions 是无人值守的,写文章、推代码、发布全链路自动完成,不需要自己记着先本地构建再推送。
5.2 Netlify 和 Vercel 的极速部署体验
如果你觉得 GitHub 的连接速度不够理想,或者压根想少跟 Git 仓库打交道,Netlify 就是第一选择。它在易用性上做到了极致:打开 Netlify 官网,选择从 Git 导入仓库,选择仓库,填两个字段,点击部署,完事。
关键字段:
- Build command:
hugo --minify - Publish directory:
public
然后还要在 Netlify 的后台设定环境变量,一般用不到,但如果你锁定了 Hugo 版本,需要在 Environment Variables 里加一条:
HUGO_VERSION=0.125.7Netlify 的自动检测很聪明,默认识别 Hugo 项目并直接构建。部署完成后,你还会得到一个.netlify.app的二级域名,可以直接访问。绑定自定义域名就在 Domain settings 里加一个 CNAME 解析即可。
Vercel 的操作与 Netlify 大同小异,几乎完全一样,只是在构建命令处使用hugo --minify,发布目录填public。它也被我用在其它前端项目上,如果你想博客之外顺带托管点什么,Vercel 是更是一站式的选择。
我用 Netlify 部署过一个公司文档站,整个部署配置不到五分钟就完成了。对于预算不足或者不想管服务器的人来说,这条路线非常顺手。
5.3 排查清单:我踩过的七个大坑
这条路走下来,你大概率会踩几个坑。我把真实经历整理了一张排查清单,按出现的频次排序:
问题一:本地能看到文章,部署到 GitHub Pages 后一片空白几乎都是 baseURL 填错了。Pages 的路径是基于仓库名的,如果你的仓库名不是username.github.io,而是myblog,访问地址是https://username.github.io/myblog/,那 baseURL 必须填https://username.github.io/myblog/。如果填的是https://username.github.io/,所有资源路径都会从根路径找,结果自然是全面 404。排查指令:在浏览器开发者工具里看 Network 面板,发现资源地址都是/xxx/css/main.css这种,就是 baseURL 根路径设置不对,改成https://username.github.io/仓库名/就能解决。
问题二:新文章半天不出现绝大多数是因为draft: true。写文章时,这个字段默认是 true,发布前记得手动改成 false,或者干脆用hugo new posts/xxx.md --kind default绕过默认草稿模板。更稳妥的做法是写一个自己的 archetype 文件,里面把 draft 直接设为 false。
问题三:图片可以显示,但在列表页一直空白列表页空白,往往不是图片本身的问题,而是摘要(summary)生成规则的问题。Hugo 会在列表页自动截取正文前若干字符作为摘要,如果正文第一段恰好是一张图片,摘要里就是空的。解决方案很简单,在文章 Front Matter 里加一行:
summary: "这是一段亲手写的文章摘要,不会截错"列表页就稳定了。
问题四:主题的示例内容不断出现在我的站点里这就是复制 exampleSite 的副作用。这个目录本身是主题为了让用户看到效果的示例内容,复制过来意味着文章、项目、头像全部带过来了。如果你不想用示例内容,可以不复制,只复制配置文件,然后用hugo new创建自己的内容,内容多了之后,示例内容的影响自然就被覆盖了。
问题五:GitHub Actions 一直构建失败第一反应是看 Actions 日志的报错位置。我印象最多的两个原因是:hugo-version 填了一个不存在的版本(比如拼错了),以及缺少 extended 参数导致 SCSS 报错。还有一个无法忽略的点是:推送分支如果写了main,但你的默认分支是master,动作永远不会触发。三个点都过一遍,基本没有解决不了的。
问题六:自定义域名开了,HTTPS 就是不开在 GitHub Pages 上设置自定义域名后,HTTPS 的自动申请需要一些时间,有时候要等几分钟甚至更久。如果你开了某个功能比如“Enforce HTTPS”,但证书一直处于“pending”状态,多半是因为 DNS 配置还没生效。检查你的 DNS 记录是否指向185.199.108.153等 Pages 的固定 IP,或者使用 CNAME 你的用户名.github.io。每次改 DNS 后,等约十几分钟再刷新看。
问题七:改了 config 文件,Hugo server 没反应这多半是 yaml 的缩进问题。YAML 对缩进极其敏感,多一个空格少一个空格都可能让配置文件解析失败。Hugo 会在终端报错,并告诉你是第几行出错。这时候我最常用的排查方式是:用编辑器打开配置文件,开启“显示空格”功能,逐行检查缩进。别嫌幼稚,省下的时间绝对值得。
5.4 部署后的事:SEO、RSS 与持续更新
部署完成,写文章,这事还没完。想让别人搜到你,该做的 SEO 基础工作还是要做。Hugo 自带 SEO 优化机制,不过你得自己做好三个配置:一是在hugo.toml里开启 sitemap,默认就开启,但你可以在配置里加中文说明;二是在 head 模板里加 meta description 和 OG 标签,大部分主题已经内置;三是如果主题没有生成 RSS,你需要确认自己在布局里放置了 RSS 链接。
我记得主题 Toha 内置了 RSS 生成,位置在https://你的域名/index.xml,这个就是标准的 RSS 订阅源。如果你的主题没生成,在layouts/_default目录下放一个rss.xml模板,Hugo 就会自动生成。
还有一个细节:在 config 文件中打开enableGitInfo = true,页面底部会显示“最后更新于”相关信息,对技术文章的信任度有很大提升。不过依赖 git 信息,所以每次发布后别忘了把内容提交到仓库,这样最后更新时间才是准确的。
持续更新方面,我自己的习惯是:每次写完文章,一条命令搞定提交和推送:
git add . git commit -m "post: 新文章标题" git push推送完成,等一分钟左右,GitHub Actions 执行完,站点就更新了。这个流程已经成为肌肉记忆,我觉得这是用 Hugo 最大的红利——随时随地写作,发布就是一次 push,没有运维负担。
我个人在实际操作中还有个体会:Hugo 的学习曲线主要体现在模板布局,如果只是写作和部署,基本半天就能完全掌握。前期不要贪心,先用成熟主题、少动模板,把写作和发布闭环跑通,等熟悉后,再试着改一改颜色、加一个短代码、调整一下列表页布局,每次动手都是对 Hugo 更深入的理解。
最后分享一个小技巧:在 content 目录下按年份分子目录组织文章,比如content/posts/2024/hello.md,配置文件里设置permalinks规则:
permalinks: posts: /:year/:month/:slug/这样你的文章链接就是https://你的域名/2024/10/hello/,比默认的https://你的域名/posts/hello/更适合做长内容积累的站点,链接天然带上时间维度,对 SEO 也有好处。这算是我自己文章写了一百多篇后最满意的优化之一。