先说个我自己的经历。当时刚把 Hexo 搭好,兴冲冲地敲下hexo new "我的第一篇博客",结果打开浏览器一看,文章完全没有出现在页面上。查了半天才发现草稿和文章不是一回事,文件名和标题也不是一回事,教程里随手一带而过的“Scaffold”更是让我绕了一大圈。这篇就把这些内容一次讲透,包括新文章的创建、草稿的预览与发布、关于/标签/分类/归档/自定义页面的建立,以及模板(Scaffold)和文件名&博客标题背后的逻辑。整篇文章都是实操记录加踩坑实录,没有什么深奥的理论,适合刚搭好博客准备正式开写的人,也适合写了几篇之后回来补课的朋友。
1. 先把“写一篇文章”这件事拆明白
很多人以为hexo new就是简简单单生成一个文件,其实它背后做的事情不少,而且很多问题都出在你对文件名、标题、URL 这几个概念的理解上。我先把这条命令拆开讲。
1.1 一条 hexo new 命令,Hexo 在背后做了什么
在 Hexo 博客根目录执行:
hexo new "Hello World"之后你去source/_posts/目录看一眼,会发现多了一个Hello-World.md文件。这个文件是 Markdown 格式的,打开它大概长这样:
--- title: Hello World date: 2024-06-01 12:00:00 tags: ---在新版本里可能没有 tags 这一行,但核心的 front-matter 基本都是这个结构。hexo new做的事其实有三件:第一,去scaffolds/目录找到对应的模板文件;第二,把模板里的变量替换成你给的标题、当前日期;第三,在source/_posts/下生成一个符合命名规则的新文件。
如果你执行的是:
hexo new page "about"那就是另一条路径,会在source/about/目录生成一个index.md。这里能看到“文章”和“页面”在 Hexo 里的位置就不一样了,后面章节会细讲。
注意:命令行里的标题建议始终加引号。不加引号直接
hexo new hello world,shell 会把 hello 和 world 拆成两个参数,部分版本的 Hexo 会报错或者行为异常,加引号是最稳妥的做法。
1.2 文件名里的 title 和页面大标题里的 title,是两个东西
这是新人最容易懵的地方。hexo new "Hello World"生成了Hello-World.md,文件名里的Hello-World是文件的“后端名字”,它决定了文章的 URL。而 front-matter 里的:
title: Hello World才是浏览器页面上显示的大标题,也决定你生成 HTML 之后的<title>标签和页面顶部的标题文字。
所以严格来说,文件名的 slug 和页面显示的 title 是可以互相独立的。你想让 URL 是英文,页面显示中文,完全没问题。比如:
hexo new "first-post"然后把文件里的 title 改成:
title: 我的第一篇博客这样 URL 是https://你的域名/first-post/,页面上显示的却是中文标题。我现在的习惯就是这个:文件名的 slug 用英文短横线格式,front-matter 的 title 写中文或英文随意,目录名保持干净。
1.3 中文标题还是英文文件名?我的习惯
有些朋友图省事,直接:
hexo new "我的第一篇"生成的文件名就是我的第一篇.md,URL 里也是一长串中文。这样做不是不行,但有几个问题:一来中文 URL 在某些旧环境或者第三方引用时会自动转成百分号编码,又长又难看;二来在 Git 提交和后续改名时,中文文件名偶尔会出现编码相关的麻烦。我的建议是文件名的 slug 统一用英文、数字、短横线,中文标题放到 front-matter 里。这样你在本地折腾、换主题、改配置的时候都会省心很多。
2. 模板(Scaffold):让每篇新文章都自带“默认配置”
Scaffold 这个词看着高大上,翻译成大白话就是“模板”。你每执行一次hexo new,Hexo 都会去scaffolds/目录里拿相应的模板文件作为骨架,把你给的标题和当前时间塞进去,生成一篇带着基本格式的新文章。理解这一点,你的写博客效率能直接上一个台阶。
2.1 Hexo 自带的三个模板,位置和默认内容
正常安装完 Hexo 后,根目录下会有一个scaffolds/文件夹,里面默认放三个文件:
post.md:hexo new用的文章模板draft.md:hexo new draft用的草稿模板page.md:hexo new page用的页面模板
默认内容大致是:
--- title: {{ title }} date: {{ date }} tags: ---post.md里多了 date,draft.md里也可能没有 date 或 tags,取决于版本。但逻辑是一样的:{{ title }}和{{ date }}是变量,由 Hexo 在生成文件时自动替换。
2.2 往模板里塞常用字段
默认模板太朴素了,而且每次写完新文章都要补一堆 front-matter 也很烦。我一般会在post.md里加上一些我固定要用的字段,例如:
--- title: {{ title }} date: {{ date }} updated: {{ date }} tags: categories: comments: true toc: true cover: ---这样每次新建文章,自动就带上了评论开关、目录开关、封面字段,你只需要填内容就行。各个主题支持的字段不一样,但大部分 Hexo 主题都会认识comments、toc、cover、tags、categories这些常见字段。你完全可以按自己的主题去调整。
如果你有一些文章是“资源帖”、有一些是“日记”,甚至可以建一个scaffolds/link.md或者scaffolds/diary.md,然后创建文章时指定模板:
hexo new link "友链" hexo new diary "今日记录"去scaffolds/里加一个link.md、diary.md就行了,创建时 Hexo 会自动找对应模板。这是一个挺多老玩家会用的操作,教程里很少讲。
2.3 模板里可以用的变量
除了{{ title }}和{{ date }},模板里还支持一些别的变量,常见的包括:
| 变量 | 说明 |
|---|---|
{{ title }} | 文章标题,就是你命令行输入的内容 |
{{ date }} | 创建时间,取当前时间 |
{{ layout }} | 使用的模板名,比如 post、draft、page |
{{ slug }} | 文件名对应的 slug 部分 |
你在自定义模板时,照抄这些变量名就行。我把模板里的date改成datetime之类是行不通的,Hexo 只认这一套变量格式,想加自定义字段得使用 front-matter 配置或者自己写插件,对绝大多数个人博客来说完全用不上。
踩坑提示:修改模板之后,已经生成的文件不会自动更新。模板只影响“之后新建”的文章,老文章要改还是得手动去改文件。别问我怎么知道的,我曾经改完模板发现一堆老文章全是旧格式,一个一个补 tags 补到眼花。
3. 草稿流程:没写完的文章不要出现在博客上
如果你一开始用的是hexo new draft,那这篇文章默认不会出现在博客列表里。草稿机制的用途非常明确:让你写了一半、不想公开的东西,安安静静躺在本地。
3.1 草稿和普通文章的区别
普通文章放在source/_posts/,草稿放在source/_drafts/。生成静态文件时,Hexo 默认不会把_drafts里的内容渲染到public/。所以就算你本地hexo generate也不会有草稿的痕迹,更不会部署到线上。这就是草稿最核心的价值。
创建草稿命令:
hexo new draft "草稿标题"然后source/_drafts/下多了一个草稿标题.md文件,front-matter 里的内容很简单,一般就是 title 和 tags。这种文件你想怎么写就怎么写,保存随时关,不会影响线上内容。
3.2 预览草稿的两种姿势
写完半成品想在本地看看效果,有两条路。
第一条,启动本地服务时带上草稿参数:
hexo server --draft这样草稿也会被渲染,打开http://localhost:4000就能看到草稿页面。注意,如果你带上了--draft,正常文章不受影响,两种都会显示。
第二条,直接把草稿“转正”后再预览:
hexo publish "草稿标题"这条命令会把source/_drafts/草稿标题.md移动到source/_posts/下。移动完成后,这篇文章在本地服务器就能像普通文章一样预览了。
我个人的习惯是:没写完的一律用草稿,想预览就用hexo server --draft,尽量不提前 publish。因为一旦 publish 到_posts,万一中途想放弃写,还得手动去_posts里删除文件,多一道麻烦。而且草案的 front-matter 里没有 date,发表时会自动补上发布当天的时间,等于发布了就定了永久时间戳,提前 move 会把 commit 历史搞得很乱。
3.3 转正、改名、删草稿的细节
用hexo publish转正草稿时,你可能踩到一个坑:标题带空格的时候命令怎么写。稳妥做法是带引号:
hexo publish "我的半成品文章"如果你在_drafts里手动改过文件名,publish 时就跟文件名走,不带引号也能识别。这部分我建议直接试一次,印象里文件名不带.md后缀就能匹配。
删除草稿也很简单,直接去source/_drafts/把对应的.md文件删掉就行,不用跑命令。如果你已经把它 publish 到了_posts,再删就得去_posts目录删,同时清理一下public缓存,重新部署才生效。
4. 本地预览与发布部署的完整闭环
写博客不能写完直接部署,除非你想经常看到一堆错别字挂在线上。本地预览、检查、再部署,这一套流程建议固定下来。
4.1 hexo server 预览:端口、热更新、草稿参数
本地预览最常用一条命令:
hexo server默认访问地址是http://localhost:4000。如果你 4000 端口被占用了,可以换端口:
hexo server -p 3000我用过的版本里,大部分主题的hexo server都支持热更新:你改 Markdown 文件保存后,页面会自动刷新或者你手动刷一下就生效。但要注意,改_config.yml这种配置文件时,某些主题不会热更新,需要重启hexo server才能看到效果。
配合草稿的话就是hexo server --draft。如果你还开了--watch之类的参数,也可以在启动时加上,但一般情况下默认就够用了。
4.2 发布前我固定会做的一套检查
每次发布之前,我有一套自己的检查清单,看起来琐碎,但吃过的亏都在这:
- 通读一遍文章,确认没有错别字,图片路径是否正确,图片是否在
source/images/下。 - 看 front-matter 里的
date和updated是否合理。想改发布时间,直接改date字段就行,不要依赖hexo publish自动生成的时间。 - 检查
tags和categories是否写对了。分类是文章层级概念,标签是平级的,两者别混。 - 本地
hexo clean && hexo generate,然后打开public/目录确认生成结果正常。 - 再
hexo server本地预览一次,在浏览器里实测文章布局、评论、目录、封面这些元素。 - 最后才执行
hexo deploy。
如果你是在多人协作或者频繁换电脑场景下,建议每次操作前先git pull,部署后立刻git push,避免本地文件覆盖远程版本。这个属于另一篇的范畴,但真踩过坑的人会懂我为什么要提。
4.3 部署到 GitHub Pages:三条命令之外的一些经验
部署到 GitHub Pages,前提是_config.yml里已经配置好 deploy 的仓库地址和分支,并且装好了部署插件。如果没有配置,先去安装hexo-deployer-git,然后在_config.yml里写上类似这样的内容:
deploy: type: git repo: git@github.com:你的用户名/你的仓库.git branch: gh-pages不同主题、不同分支设置不一样,页面托管在main分支还是gh-pages分支,要按你之前搭建时的约定来。部署命令就三条:
hexo clean hexo generate hexo deploy我强烈建议养成“先 clean 再 generate 再 deploy”的习惯。不要图省事直接hexo d,因为清理不彻底时,旧的静态文件可能残留,常见表现就是你删了某篇文章,线上却还挂着旧页面。部署完之后打开线上地址看一眼,确认没问题再关终端。
5. 页面(Page)怎么建:关于、标签、分类、归档、自定义页面
写博客不只是写文章,站点里还得有“关于我”“标签墙”“分类区”这些页面。Hexo 里这些统称 Page,它们的建法和 Post 有一点区别,我单独拎出来讲。
5.1 页面和文章的本质区别
文章(Post)放在source/_posts/下,按时间倒序展示在博客首页列表里。页面(Page)放在source/某个目录/index.md下,不在文章列表里展示,而是通过菜单链接或者直接输入 URL 访问。创建页面的命令:
hexo new page "about"这条命令会在source/about/目录生成一个index.md文件,也就是source/about/index.md。同理:
hexo new page "tags" hexo new page "categories" hexo new page "archives" hexo new page "links"都会在source/下新建对应目录,里面放着index.md。每个页面和文章一样,都有自己的 front-matter。这些页面内容写什么、如何展示,很大程度由主题决定。
5.2 标签页和分类页的搭建坑点
标签页和分类页比较特殊。你要想让页面真正变成“标签聚合页”或“分类聚合页”,光创建页面是不够的,还得在页面的 front-matter 里指定类型,比如:
--- title: 标签 date: 2024-06-01 12:00:00 type: "tags" ---分类页同理:
--- title: 分类 date: 2024-06-01 12:00:00 type: "categories" ---然后还要去主题的_config.yml里配置菜单导航,把菜单项指到对应地址。大部分主流主题里都有类似这样的配置:
menu: home: / about: /about tags: /tags categories: /categories archives: /archives不同主题的字段名会不一样,有的主题要求type: tags改成type: "tags"都没问题,但主题如果没有这个聚合页布局,光指定 type 也不会生效。我建议在搭建主题时先看一眼主题自带文档,确认它支持的页面类型。
一个小提醒:标签页和分类页的 front-matter 里,date是用页面创建日期还是无所谓,一般不会有影响。但如果你用了某些统计插件,页面时间可能会影响“最近更新”之类的列表排列,所以建议设置一个合理的日期。
5.3 归档页、关于页和自定义页面怎么搞
归档页在很多主题里是自带功能,你甚至不用单独建archives页面,访问/archives/就能看到按时间归档的文章列表。如果你的主题没做归档页,重复上面的流程:hexo new page "archives",然后在页面里选择主题对应的归档布局,或者直接在 index.md 里写一段说明文字。
关于页最常规,创建完页面之后直接在里面写几段自我介绍、联系方式、友情链接什么的就行。这个页面本质上是静态 Markdown 渲染出来的,没有特殊布局,就是“正文页面”。
自定义页面就更自由了。比如你想做个“项目展示页”,可以:
hexo new page "projects"然后在source/projects/index.md里自己排版内容,或者写一个自定义的布局页面。有些主题允许你在某个 Page 的 front-matter 里指定layout: projects,然后在layout/目录下写一个对应布局文件,这是进阶玩法,对普通用户来说不折腾更好。
6. 常见问题与排查实录
最后这部分,把我在实际操作中遇到过的典型问题和排查思路整理出来,基本都能往前翻章节找到对应内容,但这里直接给你速查版本。
6.1 文章建好了,浏览器里就是看不到
可能性按概率排序:
- 文章建成了草稿,文件在
source/_drafts/而不是source/_posts/。用hexo new draft创建就会出现这种情况,需要hexo publish转正,或者本地预览时带--draft。 - 文章位于
_posts里但 front-matter 里的date是未来时间,Hexo 默认不会渲染未来文章。检查一下时间,或者不要设置未来日期。 - 首页列表按 reading 时间或创建时间排序,你刚写的文章排到了很后面。大多数主题有“旧文置顶”或“新文置顶”策略,翻几页看看。
- 生成了静态文件但浏览器缓存了旧页面,开个无痕窗口强制刷新一下。
排查时最直接的办法:到public/目录里搜一下文章标题对应的 HTML 文件,看看是否存在。如果没有,说明生成阶段就有问题;如果有,说明是浏览器缓存或者部署问题。
6.2 front-matter 里的配置不生效
最常见的是categories和tags写错了层级。先检查格式缩进。front-matter 是 YAML 格式,一个缩进错了,整个字段就可能被 Hexo 忽略。比如:
tags: - Hexo - 博客如果写成:
tags: - Hexo - 博客这个实际上也能解析,但千万不要在tags和-之间随意混用空字符。真遇到不生效,先打开页面源码看对应的 HTML 结构里有没有该字段,再回头改 YAML。
另一个很常见的问题是comments: false不生效。很多主题的评论开关不是读文章 front-matter 的comments,而是主题配置里的全局开关。所以你想单独关某篇文章评论,先确认主题文档里用的是comments字段还是别的字段,别照搬某些老帖子的教程。
6.3 标签页分类页空白 / 样式不对
标签页、分类页是空的,最常见原因是页面的 front-matter 里没有加type: "tags"或者type: "categories",导致主题不知道该怎么渲染这个页面。加了 type 还是空白,就去主题配置里看是否有类似tags: /tags的菜单项,并且确认页面生成后访问的是/tags/这个 URL。
样式不对一般就是主题版本和页面结构不匹配,比如主题更新之后这些聚合页布局变了,但你还在用旧式 front-matter。去主题的 GitHub 文档查一下它要求的写法,照着改就行。
还有一个容易被忽略的点:如果你的站启用了permalink自定义功能,页面的 URL 可能与/tags/不同。比如配置了permalink: :year/:title/,那标签页可能变成/:year/:title/,菜单链接也要跟着改。
6.4 部署后样式全没了
hexo deploy之后线上婚纱一样的页面突然白得吓人,大概率是路径问题。博客配置里:
url: https://你的域名 root: /如果你把博客部署在子目录下,比如https://你的域名/blog/,那root必须设置为/blog/。忘记改的话,本地预览时 CSS、JS、图片的相对路径正常,部署到线上后全部 404,页面就“裸奔”了。
遇到这种状况,第一步先 F12 打开控制台,看资源加载报错路径是/assets/...还是/blog/assets/...,确认 root 配置是否正确。然后hexo clean && hexo generate && hexo deploy重新来一遍,因为 clean 会清掉缓存里的旧路径,不 clean 的话改配置可能不生效。
我给你一个我个人一直在用的固定套路:每次部署完,先在浏览器无痕窗口打开线上地址,确认页面样式、文章内容、菜单链接都没问题,再关电脑。宁可麻烦这一下,也不要隔几天刷到自己博客丑兮兮的样子。
再单独说一个小技巧:如果你发现某些文章页面的标题和文件名对不上,完全不用慌张,去那个 md 文件的 front-matter 里改title字段就行,文件名随意。站点标题、文章标题、URL 这三者本来就是关在三个不同笼子里的鸟,你理解了它仨是互不影响的,Hexo 就算入门过半了。