目标读者:完全没接触过前端/博客的”小白”。
跟着做,你会在 1~2 小时内拥有一个和本博客(Sky Blog)一样的、能在线访问的博客。
本教程所有命令在 Windows + Git Bash 下书写,macOS/Linux 用户只需把 git 换成同款命令即可。


目录


第 0 步:先搞懂 4 个概念

在动手之前,先花 5 分钟明白”我们到底在做什么”。用大白话解释:

概念 是什么 类比
静态博客 所有网页在本地提前做好(纯 HTML/CSS/JS),别人访问时直接”发卡片”给他 印刷好的传单,别人来拿现成的
Hexo 一个”工厂”:输入 Markdown 文章 → 输出一堆 HTML 网页文件 你写中文 → 机器帮你翻译成网页
GitHub Pages GitHub 提供的免费网页托管,绑定到你的仓库 免费租了一间房子放你的传单
Markdown 一种”加了记号”的纯文本,# 是标题、** 是加粗 记笔记时用 # 表示大标题

整体流程(全程就这一个循环):

写文章(.md)  →  hexo generate 生成网页(public/)  →  推送到 gh-pages 分支  →  访问 https://你的用户名.github.io/仓库名/

记住这条线,后面每一步都是围着它转的。


第 1 步:准备环境(15 分钟)

你需要 4 样东西,全部免费

1.1 安装 Node.js(博客工厂的动力源)

  1. 打开 https://nodejs.org/zh-cn ,下载 LTS 版(如 20.x)
  2. 一路 Next 装完(默认即可)
  3. 验证是否装好(打开 Git Bash,输入):
node -v      # 应输出 v18 或更高,如 v20.11.0
npm -v # 应输出 10 或更高

1.2 安装 Git(版本管理 + 推送到 GitHub)

  1. 打开 https://git-scm.com/download/win 下载安装
  2. 安装向导里”默认选择”即可(建议:默认编辑器选 Notepad++ 或 VS Code)
  3. 安装后右键桌面,会出现 “Git Bash Here” —— 后面所有命令都在这个窗口敲
  4. 验证:
git --version     # 应输出 git version 2.x

1.3 注册 GitHub 账号

  1. 打开 https://github.com 注册(用户名决定你的博客地址)
  2. 登录后,新建一个空仓库:
    • 右上角 + → New repository
    • Repository name:myblog(随便起,英文小写)
    • 不要勾选 “Add a README file”
    • Create repository

1.4 安装 VS Code(写文章用的编辑器)

  1. 打开 https://code.visualstudio.com 下载安装
  2. 装好后在任意文件夹右键 → “Open with Code”

✅ 环境就绪标志:node -vgit --version 都有输出,GitHub 账号能登录。


第 2 步:搭建 Hexo 骨架(10 分钟)

2.1 安装 Hexo 命令行工具

npm install -g hexo-cli
hexo -v # 能看到版本号即成功

2.2 创建博客项目

# 找一个你喜欢的目录(比如 D:\),进入后执行:
cd /d

# 用 hexo 初始化(myblog 是文件夹名,和仓库名一致)
hexo init myblog
cd myblog

# 安装依赖(把 package.json 里列的库都装好)
npm install

装完你会看到这样一个目录结构(先认识,不用背):

myblog/
├─ _config.yml # ★ 站点主配置(改这里)
├─ package.json # 依赖清单
├─ scaffolds/ # 模板(新文章会套用)
├─ source/ # ★ 你写的东西都在这里
│ ├─ _posts/ # 文章文件夹
│ └─ img/ # 图片资源
└─ themes/ # 主题文件夹
└─ landscape/ # 自带的默认主题(稍后换成 Sakura)

2.3 第一次预览

npx hexo server
# 浏览器打开 http://localhost:4000

能看到一个默认博客页面 = 骨架搭好了。按 Ctrl + C 停掉。

如果 hexo init 很慢或失败(网络问题),可以手动搭:

mkdir myblog && cd myblog
npm init -y
npm install hexo hexo-server hexo-renderer-marked hexo-renderer-ejs hexo-renderer-stylus hexo-renderer-pug hexo-generator-index hexo-generator-archive hexo-generator-tag hexo-generator-category hexo-generator-feed hexo-generator-search hexo-tag-bili hexo-tag-fancybox_img

然后自己建 source/_posts/scaffolds/themes/ 文件夹即可,效果一样。


第 3 步:安装 Sakura 主题

Sakura 是本博客使用的二次元主题(原作者 honjun,MIT 协议)。

3.1 下载主题到 themes 目录

cd myblog
git clone https://github.com/honjun/hexo-theme-sakura.git themes/sakura

3.2 启用主题

编辑 myblog/_config.yml,把 theme: 改成:

theme: sakura

3.3 认识”主题两套配置”(非常重要!)

Sakura 主题有两份配置文件,它们会自动合并

文件 角色 什么时候改
themes/sakura/_config.yml 主题默认配置 极少改(它是模板)
_config.sakura.yml(自己建) 站点覆盖配置 ★ 日常改这里

⚠️ 大坑预告:两份配置的同名数组(比如 bg:menus:)会拼接而不是覆盖!
例如两边都写 bg:,最终会得到 16 张背景图,前 8 张还可能是失效的。
规则:数组字段只在一处写(本项目统一写在 themes/sakura/_config.yml)。

新建 myblog/_config.sakura.yml,先放最小内容:

# 站点名与头像
siteName: 我的博客
favicon: /img/favicon.png
avatar: /img/favicon.png

第 4 步:站点配置 _config.yml

打开 myblog/_config.yml,重点改这几处:

4.1 站点信息

title: 我的技术博客          # 浏览器标签栏标题
subtitle: '记录技术与思考' # 副标题
description: '个人技术博客' # SEO 描述
author: Sky # 作者名
language: zh-CN # 语言
timezone: Asia/Shanghai # 时区

4.2 URL 和 root(★ 子目录部署的关键)

如果你要把博客放在 https://用户名.github.io/仓库名/(项目页),必须

url: https://你的用户名.github.io/myblog
root: /myblog/ # ★ 末尾斜杠不能少

如果你要放在 https://用户名.github.io/(个人主页),改成:

url: https://你的用户名.github.io
root: /

root 决定所有资源路径的前缀。改错了,图片/样式全 404

4.3 常用字段对照表

字段 作用
permalink 文章网址格式,如 :year/:month/:day/:title/
theme 主题名(第 3 步已改)
deploy 部署配置(见第 9 步,建议留空不用
index_generator.per_page 首页每页文章数

第 5 步:主题配置 _config.sakura.yml

_config.sakura.yml 补全(这是”主题如何设置”的核心):

5.1 菜单

menus:
首页: { path: /, fa: fa-home }
归档: { path: /archives/, fa: fa-archive }
标签: { path: /tags/, fa: fa-tags }
分类: { path: /categories/, fa: fa-folder-open }
留言板: { path: /comment/, fa: fa-pencil-square-o }
友人帐: { path: /links/, fa: fa-link }
关于: { path: /about/, fa: fa-heart }

fa: 是 Font Awesome 图标名,想换图标去 https://fontawesome.com/v4/icons/ 查。

5.2 头像与 favicon

favicon: /img/favicon.png
avatar: /img/favicon.png

把你的头像图片放到 source/img/favicon.png(没有 img 文件夹就新建)。

5.3 壁纸(首页背景图)

做法一(推荐,本项目采用):直接改 themes/sakura/_config.yml

bg:
- /img/wallpaper/1.webp
- /img/wallpaper/2.webp
- /img/wallpaper/3.webp
# ...想加几张加几行
bgclass: "" # 空=原图 filter-dim=加阴影 filter-grid=横条纹 filter-dot=点点

把图片放到 source/img/wallpaper/ 下(建议 .webp 格式,体积小加载快)。

⚠️ 绝不要同时在 _config.sakura.yml 里再写 bg: —— 会变成 16 张图(数组拼接的坑)。

5.4 背景音乐(APlayer)

aplayer:
id: 19723756 # 网易云歌单 ID(这个是"飙升榜")
server: netease
type: playlist
fixed: true # 固定显示在左下角
autoplay: false # 不要自动播放(浏览器会拦)
loop: all
order: random
preload: auto
volume: 0.7

想换歌单:打开网易云音乐网页版 → 找到一个歌单 → 网址里 /playlist?id=xxxxxxxxxxxx 就是 ID。

⚠️ 网易云外链大量失效,播放器会”卡在”放不了的歌上。
本项目已把播放器改成坏链自动跳下一首(改的是 themes/sakura/layout/_partial/aplayer.ejs)。
想要最稳:把自己 mp3 放进 source/music/,改成本地播放列表。

5.5 社交链接

# PC 端(左下角)
social:
github: { url: https://github.com/你的用户名, img: /img/social/github.png }
email: { url: mailto:you@example.com, img: /img/social/email.svg }

# 移动端(汉堡菜单里)
msocial:
github: { url: https://github.com/你的用户名, fa: fa-github, color: 333 }
email: { url: mailto:you@example.com, fa: fa-envelope, color: dd4b39 }

socialimg: 需要准备图标图片放进 source/img/social/msocial 用字体图标不需要图片,更省事。

5.6 首页 START:DASH 三张卡片

startdash:
- {url: /about/, title: 关于, desc: 了解本站, img: /img/wallpaper/1.webp}
- {url: /archives/, title: 归档, desc: 全部文章, img: /img/wallpaper/2.webp}
- {url: /tags/, title: 标签, desc: 按标签浏览, img: /img/wallpaper/3.webp}

第 6 步:写第一篇文章

6.1 创建

cd myblog
npx hexo new "我的第一篇博客"

生成的文件:source/_posts/我的第一篇博客.md。用 VS Code 打开,front-matter(--- 之间的部分)写成:

---
title: 我的第一篇博客
date: 2026-08-27 18:00:00
updated: 2026-08-27 18:00:00
tags:
- 生活
categories:
- 生活
photos:
- /img/cover/cover1.jpg
---

--- 下面就是正文,用 Markdown 语法写:

# 一级标题
## 二级标题

**加粗***斜体*`行内代码`

- 列表项 1
- 列表项 2

正文里需要代码块时,单独用三个反引号包裹即可(不要和上面的示例嵌套):

console.log("代码块");

6.2 Front-matter 字段速查

--- 之间的内容叫 front-matter(文章”身份证”):

字段 必填 说明 示例
title 标题 title: 我的博客
date 发布时间 date: 2026-08-27 18:00:00
updated 更新时间 updated: 2026-08-28 09:00:00
tags 标签(可多个) tags: [技术, github]
categories 分类(可多个) categories: [技术]
photos 封面图(数组,第一张是封面) photos: [/img/cover/a.jpg]
description 列表页摘要 description: 一句话介绍
mathjax 数学公式 mathjax: true

6.3 封面图怎么设置?(重点)

Sakura 主题的封面字段是 photos 数组不是 cover!用 cover 不生效):

photos:
- /img/cover/my-cover.jpg

步骤:

  1. 建目录 source/img/cover/,把图放进去
  2. front-matter 写 photos: [/img/cover/my-cover.jpg]
  3. 重新生成 → 文章页顶部就有封面大图,列表页缩略图也用它

/ 开头的路径 = “资源根”,Hexo 会自动加上 root(如 /myblog/),最终访问
https://用户名.github.io/myblog/img/cover/my-cover.jpg

6.4 正文里插图片

把图片放 source/img/post/,正文里写:

![图片说明](/img/post/xxx.png)

6.5 标签和分类有什么用

  • 标签:一篇文章可以贴多个,如”教程””Hexo””GitHub”
  • 分类:类似文件夹,一篇最好只归一个

它们会自动生成聚合页(如 /tags/GitHub/ 列出所有 GitHub 标签文章),
前提是你按第 7 步建了标签/分类根页。


第 7 步:搞定标签/分类页(新手必踩的坑)

症状:菜单点”标签”/“分类”,页面 404 或空白。

原因:Hexo 会自动生成”单个标签页”(/tags/GitHub/),
不会自动生成”标签总览页”/tags/)——除非你手动建了页面文件。

解决:在 source/ 下新建两个文件:

source/tags/index.md

---
title: 标签
layout: tag # ★ 必须是单数 tag(不是 type: tags!)
description: 按标签浏览所有文章
---

source/categories/index.md

---
title: 分类
layout: category # ★ 必须是单数 category
description: 按分类浏览所有文章
---

为什么不是 type: tags Sakura 主题只提供了 tag.ejs(单数)这一个模板。
type: tags 会让 Hexo 去找 tags.ejs(复数),找不到就退回通用模板,
页面变成”空壳”。用 layout: tag 才能命中正确模板。

进一步美化(可选):Sakura 自带的 tag.ejs 在”总览页”上只显示最新文章,不显示标签列表。
本项目改成了”总览页显示全部标签+文章数”(themes/sakura/layout/tag.ejs 里判断
!page.tag 时渲染 site.tags 列表),单标签页行为不变。想抄的看本项目源码。


第 8 步:本地预览与排错

8.1 常用命令

npx hexo server        # 启动本地预览 http://localhost:4000
npx hexo generate # 生成静态文件到 public/
npx hexo clean # 清缓存(改配置不生效时用)

8.2 常见报错速查

报错 原因 解决
Port 4000 is already in use 端口被占 npx hexo server -p 4001
图片/样式 404 root 配置错 检查 _config.ymlroot:
修改后页面没变 缓存 npx hexo clean && npx hexo generate
壁纸显示 CDN 默认图 数组 concat 见 §5.3,bg: 只写一处
标签页空白 没建 index.md 见第 7 步

第 9 步:部署上线到 GitHub Pages

这是最容易”翻车”的一步,按下面的推荐姿势做,稳。

9.1 把源码推到 GitHub

cd myblog

# 初始化 git(如果 hexo init 没自动做)
git init

# 关联你的远程仓库
git remote add origin https://github.com/你的用户名/myblog.git

# 第一次提交
git add .
git commit -m "init: hexo + sakura blog"
git push -u origin main

如果你仓库默认分支叫 master,就把 main 换成 master
推送要账号密码/Token:GitHub 现在要求用 Personal Access Token(Settings → Developer settings → Personal access tokens),或先跑 gh auth login 登录 CLI。

9.2 在 GitHub 上启用 Pages

仓库页面 → SettingsPages

  • SourceDeploy from a branch
  • Branchgh-pages,目录 / (root)
  • Save

注意:这里选的是 gh-pages(产物分支),不是 main(源码分支)!

9.3 部署姿势一:独立目录法(★ 推荐,本项目用这个)

原理:把构建产物复制到一个独立的 git 仓库目录,只往 gh-pages 分支推。

# 1. 生成产物
cd myblog
npx hexo clean && npx hexo generate

# 2. 准备一个"独立部署目录"(第一次做)
mkdir /d/myblog_deploy
cd /d/myblog_deploy
git init
git remote add origin https://github.com/你的用户名/myblog.git
# 先随便提交一个空提交,让分支存在
git commit --allow-empty -m "init deploy branch"
git push -u origin HEAD:gh-pages

# 3. 每次发布:清空 → 复制 → 提交 → 推送
rm -rf /d/myblog_deploy/*
cp -r /c/你的路径/myblog/public/* /d/myblog_deploy/
touch /d/myblog_deploy/.nojekyll # ★ 必须有!见下方
cd /d/myblog_deploy
git add -A
git -c http.version=HTTP/1.1 commit -m "Site updated: $(date)"
git -c http.version=HTTP/1.1 push -f origin HEAD:gh-pages

为什么不能直接 npx hexo d
当你把 myblog 文件夹本身变成 git 仓库后,hexo-deployer-git.deploy_git
会”蹭用”根目录的 .git,结果 git add -A整个源码推上了 gh-pages
GitHub Pages 找不到根 index.html → 404。这是本项目踩过的真事故,详见附录 B。

.nojekyll 是什么? 一个空文件,告诉 GitHub Pages”不要用 Jekyll 重新构建,
我给你的就是最终网页”。没有它,Jekyll 可能静默失败并沿用旧版
表现为”明明推了新代码,线上还是老样子”。

9.4 部署姿势二:GitHub Actions 自动部署(推荐长期用)

第 11 步,配一次之后每次 git push 就自动发布,本地不用装 Node。

9.5 首次访问

部署成功后等 1~2 分钟(GitHub Pages 构建需要时间),打开:

https://你的用户名.github.io/myblog/

看到自己的博客上线了 🎉 这就是全程的目标。


第 10 步:其他平台部署(Cloudflare / Vercel / Netlify)

这三个平台原理一样:连接你的 GitHub 仓库 → 填构建命令 → 平台帮你跑 → 发布
共同配置:

配置项
构建命令(Build command) npm run build(package.json 里已定义 hexo generate
输出目录(Output directory) public
Node 版本 20(在环境变量里设 NODE_VERSION=20
环境变量 PUBLIC_URL=https://你的域名

注意:在这些平台部署时,_config.ymlurl/root 要按平台给的域名改,
比如 Vercel 是 https://xxx.vercel.approot 通常是 /

10.1 Cloudflare Pages

  1. https://dash.cloudflare.comPagesCreate a projectConnect to Git
  2. 选仓库 → Framework preset 选 Hexo
  3. 填上表的 Build command / Output directory
  4. Save and Deploy,等 1~2 分钟
  5. 自定义域名:项目 → Custom domains → 填域名,Cloudflare 自动配 CNAME + HTTPS

10.2 Vercel

  1. https://vercel.comNew ProjectImport Git Repository → 选仓库
  2. Framework Preset 选 Other,Build Command 填 npm run build,Output 填 public
  3. Deploy,30 秒拿到 xxx.vercel.app
  4. 域名:Project → Settings → Domains

10.3 Netlify

  1. https://app.netlify.comAdd new siteImport an existing project → 选 GitHub 仓库
  2. Build command: npm run build;Publish directory: public
  3. Deploy site
  4. 域名:Site settings → Domain management → Add custom domain

第 11 步:GitHub Actions 自动部署

配好后,以后只做一件事:改完文章 git push,剩下全自动。

11.1 创建工作流文件

myblog/.github/workflows/deploy.yml 新建:

name: Deploy Hexo to gh-pages

on:
push:
branches: [main] # 推 main 时触发
workflow_dispatch: # 支持手动触发

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'

- name: Install dependencies
run: npm ci

- name: Build
run: npx hexo generate

- name: Deploy to gh-pages
uses: peaceiris/actions-gh-pages@v4
with:
github_token: ${{ secrets.GITHUB_TOKEN }} # 自动生成,无需手动配
publish_dir: ./public
publish_branch: gh-pages
force_orphan: true
user_name: 'github-actions[bot]'
user_email: 'github-actions[bot]@users.noreply.github.com'

11.2 提交并验证

git add .github/workflows/deploy.yml
git commit -m "ci: 自动构建并发布到 gh-pages"
git push origin main

去仓库 Actions 标签页能看到工作流在跑。绿勾 = 成功,之后每次 push 都自动发布。


第 12 步:移动端适配

12.1 主题自带能力

Sakura 自带响应式:手机访问自动隐藏侧栏、汉堡菜单、压缩字体。一般不用动。

12.2 本项目做过的微调(可参考)

themes/sakura/source/css/style.css 追加:

/* 菜单强制一行,防止换行挤到第二行 */
.site-top .lower nav.navbar ul {
display: flex;
flex-wrap: nowrap;
white-space: nowrap;
}
.site-top .lower nav.navbar ul li {
float: none;
flex-shrink: 0;
white-space: nowrap;
margin: 0 15px; /* 间距调大,触屏更好点 */
}

12.3 测试不同设备

浏览器按 F12 → 左上角切换设备图标(Ctrl+Shift+M)→ 试 375px(iPhone SE)/ 768px(iPad)/ 1280px(桌面)。

优化建议:

  • 图片转 .webp(体积小一半)
  • 首页壁纸单张 ≤ 200KB
  • 文字大小在 @media (max-width: 768px) 里适当放大

第 13 步:日常维护(写文章、改壁纸、换封面)

13.1 发新文章的标准流程

cd myblog
npx hexo new "文章标题" # 1. 创建
# 2. VS Code 编辑 source/_posts/文章标题.md(写 front-matter + 正文)
npx hexo server # 3. 本地预览检查
npx hexo clean && npx hexo generate # 4. 重新生成
# 5. 推源码(GitHub Actions 会自动发布):
git add .
git commit -m "post: 文章标题"
git push origin main
# (若没配 Actions:走 §9.3 独立目录法推 gh-pages)

13.2 换壁纸

  1. 新图放 source/img/wallpaper/
  2. themes/sakura/_config.ymlbg: 数组
  3. 重新生成 + 部署

13.3 换封面图

  1. 新图放 source/img/cover/
  2. 改文章 front-matter 的 photos:
  3. 重新生成 + 部署

13.4 备份

源码推到 main 就是最好的备份。定期:

git push origin main

附录 A:命令速查

用途 命令
装依赖 npm install
本地预览 npx hexo server
创建文章 npx hexo new "标题"
创建独立页 npx hexo new page 路径
生成静态文件 npx hexo generate(简写 hexo g
清缓存 npx hexo clean
查看 git 状态 git status
提交 git add . && git commit -m "说明"
推源码 git push origin main
推产物(独立目录法) git -c http.version=HTTP/1.1 push -f origin HEAD:gh-pages
杀 node(Windows) PowerShell: Stop-Process -Name node -Force;CMD: taskkill /F /IM node.exe

附录 B:血泪避坑清单

🚨 1. 禁用 hexo d(本项目最大事故)

站点根目录本身是 git 仓库时,hexo deploy 会把整个源码 force push 到 gh-pages
导致线上 404(找不到根 index.html)。
只用独立目录法(§9.3)或 GitHub Actions(§11)。

🚨 2. 主题配置数组是”拼接”不是”覆盖”

_config.sakura.ymlthemes/sakura/_config.yml 的同名数组会 concat。
bgmenusstartdash 都中招。数组只写一处。

🚨 3. 子目录部署必须用 url_for()

主题里如果直接”字符串拼接”出路径(如 theme.cdn + '/img/xx'),子目录部署会 404。
Sakura 的 head.ejs(背景图)、startdash.ejsheadertop.ejs(头像)都踩过,
本项目已改为 url_for() 处理。改主题时遇到路径拼接,优先用 url_for()

🚨 4. type: tags 会 404,要用 layout: tag

Sakura 只有 tag.ejs 单数模板。见第 7 步。

🚨 5. GitHub Pages 必须放 .nojekyll

否则 Jekyll 可能静默失败并沿用旧版。每次部署 touch .nojekyll

🚨 6. 推送失败先试三板斧

git push origin main                              # ① 默认
git -c http.version=HTTP/1.1 push origin main # ② 解决 HTTP/2+代理 TLS 不兼容
env -u HTTP_PROXY -u HTTPS_PROXY git -c http.proxy= -c https.proxy= \
-c http.version=HTTP/1.1 push origin main # ③ 绕过代理直连

🚨 7. 网易云歌单外链大量失效

播放器会卡在放不了的歌。换歌单 ID 治标,本地 mp3 治本。


恭喜读到这里! 现在你已经能从零搭起并上线一个 Hexo + Sakura 博客了。
剩下就是多写、多改、多看 npx hexo server 的实时预览。
有问题就回看本教程的排错表,或者到 Hexo 文档 查。