Hexo + Butterfly 博客完整配置指南
本文档记录了我的 Hexo 博客从零开始配置 Butterfly 主题的完整过程,包括所有操作步骤、文件说明和后续优化方法。
一、项目结构说明
1.1 完整目录树
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| myblogs/ # 博客根目录 ├── _config.yml # Hexo 站点配置文件(核心) ├── _config.butterfly.yml # Butterfly 主题配置文件(核心) ├── package.json # Node.js 项目配置,管理依赖 ├── package-lock.json # 锁定依赖版本 ├── node_modules/ # npm 依赖包(自动生成,不要手动修改) ├── themes/ # 主题目录 │ └── butterfly/ # Butterfly 主题源码 │ ├── _config.yml # 主题默认配置(不要直接修改) │ ├── layout/ # 主题模板文件 │ ├── source/ # 主题静态资源 │ └── languages/ # 主题多语言文件 ├── source/ # 博客源文件(你的内容) │ ├── _posts/ # 文章目录 │ │ ├── hello-world.md # 示例文章1 │ │ └── 外设认证测试方案.md # 示例文章2 │ ├── about/ # 关于页面 │ │ └── index.md # 关于页面内容 │ ├── img/ # 图片资源 │ │ ├── avatar.svg # 侧边栏头像 │ │ └── default-cover.svg # 文章默认封面 │ ├── css/ # 自定义样式 │ │ └── custom.css # 自定义CSS样式 │ └── js/ # 自定义脚本 │ └── sidebar-search.js # 侧边栏搜索功能 ├── public/ # 生成的静态网站(npm run build 后生成) ├── scaffolds/ # 文章模板 │ ├── post.md # 新文章模板 │ ├── page.md # 新页面模板 │ └── draft.md # 草稿模板 └── docs/ # 项目文档 └── superpowers/ ├── specs/ # 设计规范 └── plans/ # 实施计划
|
1.2 核心文件说明
_config.yml(Hexo 站点配置)
- 作用:控制整个博客的基础设置
- 重要配置项:
- 站点信息:标题、作者、语言、时区
- URL 配置:网站地址
- 主题选择:
theme: butterfly
- 搜索配置:本地搜索索引路径
- 部署配置:GitHub Pages 部署信息
_config.butterfly.yml(Butterfly 主题配置)
- 作用:控制 Butterfly 主题的外观和功能
- 重要配置项:
- 导航菜单:首页、归档、分类、标签、关于
- 侧边栏:头像、简介、社交链接、统计卡片
- 搜索功能:本地搜索开关
- 文章卡片:摘要长度、封面显示
- 注入功能:自定义 CSS/JS 的加载
二、完整配置过程
2.1 Task 1:安装 Butterfly 主题
操作步骤:
1 2 3 4 5 6 7 8 9 10 11 12
| rm -rf themes/butterfly
git clone https://github.com/jerryc127/hexo-theme-butterfly.git themes/butterfly
cp themes/butterfly/_config.yml _config.butterfly.yml
npm run clean npm run build
|
文件变化:
- 新增:
themes/butterfly/ 整个主题文件夹
- 新增:
_config.butterfly.yml 主题配置文件
关键点:
_config.butterfly.yml 是主题配置的独立副本,修改它不会影响主题源码
- 主题源码在
themes/butterfly/ 中,一般不需要直接修改
2.2 Task 2:配置站点基础信息
修改文件: _config.yml
修改内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| title: 张宇的博客 subtitle: '记录学习、技术和生活' description: '一个用于记录学习笔记、技术实践和个人思考的简约博客。' keywords: 技术博客,学习笔记,Hexo,Butterfly author: 张宇 language: zh-CN timezone: Asia/Shanghai
url: https://zhangyu10086.github.io
theme: butterfly
search: path: search.xml field: post content: true format: html
|
依赖检查: package.json
确保包含搜索插件:
1
| "hexo-generator-search": "^2.4.3"
|
验证:
1 2 3 4
| npm run clean npm run build
test -f public/search.xml && echo "搜索索引生成成功"
|
2.3 Task 3:配置侧边栏、菜单和搜索
3.1 创建头像文件
文件路径: source/img/avatar.svg
内容:
1 2 3 4 5 6
| <svg xmlns="http://www.w3.org/2000/svg" width="240" height="240" viewBox="0 0 240 240"> <rect width="240" height="240" rx="120" fill="#eef4ff"/> <circle cx="120" cy="92" r="42" fill="#8fb8ff"/> <path d="M48 206c10-44 39-68 72-68s62 24 72 68" fill="#5f8ee6"/> <text x="120" y="224" text-anchor="middle" font-size="20" fill="#335" font-family="Arial, sans-serif">Blog</text> </svg>
|
说明: 这是一个简单的 SVG 头像,你可以替换成自己的图片(建议尺寸 200x200 以上)。
3.2 创建关于页面
文件路径: source/about/index.md
内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| --- title: 关于我 date: 2026-07-17 00:00:00 type: about ---
你好,我是张宇。
这里是我的个人博客,用来记录学习笔记、技术实践和生活思考。
后续我会在这里整理:
- 编程学习记录 - 项目实践经验 - 工具使用心得 - 个人成长思考
|
说明: type: about 告诉 Hexo 这是一个特殊页面类型。
3.3 配置 Butterfly 主题
修改文件: _config.butterfly.yml
主要配置项:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
| menu: 首页: / || fas fa-home 归档: /archives/ || fas fa-archive 分类: /categories/ || fas fa-folder-open 标签: /tags/ || fas fa-tags 关于: /about/ || fas fa-user
social: fab fa-github: https://github.com/zhangyu10086 || Github fas fa-envelope: mailto:your-email@example.com || Email
avatar: img: /img/avatar.svg effect: false
aside: enable: true hide: false button: true mobile: true position: left display: archive: true tag: true category: true card_author: enable: true description: 记录学习、技术和生活 button: enable: true icon: fas fa-envelope text: 联系我 link: mailto:your-email@example.com card_announcement: enable: true content: 欢迎来到我的博客,这里记录学习、技术和生活。 card_recent_post: enable: true limit: 5 sort: date card_categories: enable: true limit: 8 expand: none card_tags: enable: true limit: 20 color: false
search: use: local_search
local_search: enable: true preload: false CDN:
algolia_search: enable: false
docsearch: enable: false
|
3.4 添加侧边栏搜索入口
文件路径: source/js/sidebar-search.js
内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
|
document.addEventListener('DOMContentLoaded', () => { const asideContent = document.getElementById('aside-content'); if (!asideContent) return;
const searchCard = document.createElement('div'); searchCard.className = 'card-widget card-search'; searchCard.id = 'card-search'; searchCard.innerHTML = ` <div class="item-headline"> <i class="fas fa-search"></i> <span>搜索</span> </div> <button class="search-card-btn" type="button" style="width: 100%; padding: 10px; margin: 10px 0; border: 1px solid var(--btn-border); border-radius: 4px; background-color: var(--btn-bg); cursor: pointer; transition: all 0.3s;"> <i class="fas fa-search"></i> 搜索文章 </button> `;
const firstCard = asideContent.querySelector('.card-widget'); if (firstCard && firstCard.nextElementSibling) { firstCard.nextElementSibling.insertAdjacentElement('afterend', searchCard); } else if (firstCard) { firstCard.insertAdjacentElement('afterend', searchCard); } else { asideContent.insertAdjacentElement('afterbegin', searchCard); }
const searchBtn = searchCard.querySelector('.search-card-btn'); if (searchBtn) { searchBtn.addEventListener('click', () => { const headerSearchButton = document.querySelector('#search-button > .search'); if (headerSearchButton) { headerSearchButton.click(); } }); } });
if (window.btf && window.btf.addGlobalFn) { window.btf.addGlobalFn('pjaxComplete', () => { const asideContent = document.getElementById('aside-content'); const existingSearchCard = document.getElementById('card-search');
if (asideContent && !existingSearchCard) { const searchCard = document.createElement('div'); searchCard.className = 'card-widget card-search'; searchCard.id = 'card-search'; searchCard.innerHTML = ` <div class="item-headline"> <i class="fas fa-search"></i> <span>搜索</span> </div> <button class="search-card-btn" type="button" style="width: 100%; padding: 10px; margin: 10px 0; border: 1px solid var(--btn-border); border-radius: 4px; background-color: var(--btn-bg); cursor: pointer; transition: all 0.3s;"> <i class="fas fa-search"></i> 搜索文章 </button> `;
const firstCard = asideContent.querySelector('.card-widget'); if (firstCard && firstCard.nextElementSibling) { firstCard.nextElementSibling.insertAdjacentElement('afterend', searchCard); } else if (firstCard) { firstCard.insertAdjacentElement('afterend', searchCard); } else { asideContent.insertAdjacentElement('afterbegin', searchCard); }
const searchBtn = searchCard.querySelector('.search-card-btn'); if (searchBtn) { searchBtn.addEventListener('click', () => { const headerSearchButton = document.querySelector('#search-button > .search'); if (headerSearchButton) { headerSearchButton.click(); } }); } } }, 'sidebarSearch'); }
|
说明: 这个脚本在侧边栏动态添加搜索卡片,点击后触发 Butterfly 自带的搜索功能。
注入脚本: 在 _config.butterfly.yml 中添加:
1 2 3 4 5
| inject: head: bottom: - <script src="/js/sidebar-search.js"></script>
|
2.4 Task 4:配置文章卡片和封面
4.1 创建默认封面图
文件路径: source/img/default-cover.svg
内容:
1 2 3 4 5 6 7 8 9 10 11 12 13
| <svg xmlns="http://www.w3.org/2000/svg" width="1200" height="675" viewBox="0 0 1200 675"> <defs> <linearGradient id="g" x1="0" y1="0" x2="1" y2="1"> <stop offset="0" stop-color="#eef4ff"/> <stop offset="1" stop-color="#d9e8ff"/> </linearGradient> </defs> <rect width="1200" height="675" rx="32" fill="url(#g)"/> <circle cx="220" cy="170" r="80" fill="#ffffff" opacity="0.55"/> <circle cx="1010" cy="520" r="120" fill="#ffffff" opacity="0.45"/> <text x="600" y="320" text-anchor="middle" font-size="58" fill="#335" font-family="Arial, sans-serif" font-weight="700">张宇的博客</text> <text x="600" y="392" text-anchor="middle" font-size="28" fill="#667" font-family="Arial, sans-serif">记录学习、技术和生活</text> </svg>
|
说明: 比例 16:9,适合文章卡片封面。
4.2 配置文章卡片显示
修改文件: _config.butterfly.yml
1 2 3 4 5 6 7 8 9 10 11 12 13
| index_post_content: method: 3 length: 220
cover: index_enable: true aside_enable: true archives_enable: true position: both default_cover: - /img/default-cover.svg
|
4.3 文章 Front Matter 示例
示例1: source/_posts/hello-world.md
1 2 3 4 5 6 7 8 9 10 11 12 13
| --- title: Hello World date: 2026-07-16 16:19:00 categories: - 博客 tags: - Hexo - Butterfly description: 使用 Hexo 创建博客后的第一篇文章,记录博客搭建的开始。 cover: /img/default-cover.svg ---
文章正文内容...
|
Front Matter 字段说明:
title: 文章标题
date: 发布日期
categories: 分类(可多个,用列表)
tags: 标签(可多个,用列表)
description: 文章描述(用于卡片摘要和 SEO)
cover: 封面图路径(可选,不设置则使用默认封面)
2.5 Task 5:添加简约视觉样式
文件路径: source/css/custom.css
内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
| :root { --zy-card-radius: 12px; --zy-card-shadow: 0 8px 24px rgba(31, 45, 61, 0.08); --zy-card-shadow-hover: 0 12px 32px rgba(31, 45, 61, 0.14); --zy-primary: #3b82f6; }
body { background: #f6f8fb; }
#aside-content .card-widget, #recent-posts > .recent-post-item, .layout > div:first-child:not(.recent-posts) { border-radius: var(--zy-card-radius); box-shadow: var(--zy-card-shadow); border: 1px solid rgba(148, 163, 184, 0.16); }
#recent-posts > .recent-post-item { transition: transform 0.25s ease, box-shadow 0.25s ease; }
#recent-posts > .recent-post-item:hover { transform: translateY(-4px); box-shadow: var(--zy-card-shadow-hover); }
#aside-content .card-info .author-info__name { font-weight: 700; letter-spacing: 0.02em; }
#aside-content .card-info .author-info__description { color: #64748b; line-height: 1.7; }
a, #nav .site-page:hover, #aside-content .card-tag-cloud a:hover, #aside-content .aside-list > .aside-list-item .content > .title:hover { color: var(--zy-primary); }
#pagination .page-number.current { background: var(--zy-primary); border-radius: 8px; }
@media (max-width: 768px) { #recent-posts > .recent-post-item, #aside-content .card-widget { border-radius: 10px; }
.layout { padding: 0 12px; } }
|
CSS 说明:
- CSS 变量定义了设计 token(圆角、阴影、主色)
- 卡片样式统一了侧边栏和文章卡片的外观
- Hover 动画让交互更流畅
- 移动端媒体查询优化小屏体验
注入 CSS: 在 _config.butterfly.yml 中添加:
1 2 3 4 5
| inject: head: - <link rel="stylesheet" href="/css/custom.css"> bottom: - <script src="/js/sidebar-search.js"></script>
|
三、常用命令
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| npm run clean
npm run build
npm run server
hexo new "文章标题"
hexo new page "页面名"
npm run deploy
|
四、项目关键文件速查
| 文件路径 |
作用 |
修改频率 |
_config.yml |
Hexo 站点配置 |
低(初始配置后很少改) |
_config.butterfly.yml |
Butterfly 主题配置 |
中(调整外观功能时) |
source/_posts/ |
文章目录 |
高(经常新增文章) |
source/css/custom.css |
自定义样式 |
中(样式调整) |
source/js/sidebar-search.js |
自定义脚本 |
低(功能扩展) |
source/img/ |
图片资源 |
中(新增图片) |
themes/butterfly/ |
主题源码 |
极低(不建议修改) |
五、后续优化指南
5.1 如何修改博客外观?
修改颜色主题
位置: source/css/custom.css
1 2 3
| :root { --zy-primary: #3b82f6; }
|
推荐颜色:
- 蓝色:
#3b82f6(当前)
- 绿色:
#10b981
- 紫色:
#8b5cf6
- 橙色:
#f97316
修改卡片样式
位置: source/css/custom.css
1 2 3 4
| :root { --zy-card-radius: 12px; --zy-card-shadow: 0 8px 24px rgba(31, 45, 61, 0.08); }
|
调整建议:
- 更圆润:增大
--zy-card-radius 到 16px 或 20px
- 更扁平:减小阴影透明度(0.08 → 0.04)
- 无阴影:设置为
none
修改侧边栏内容
位置: _config.butterfly.yml
1 2 3 4 5 6 7
| aside: card_author: description: 记录学习、技术和生活 card_announcement: content: 欢迎来到我的博客... card_recent_post: limit: 5
|
5.2 如何添加新功能?
添加评论系统
位置: _config.butterfly.yml
1 2 3 4 5 6 7 8 9
| comments: use: Valine
valine: appId: your_leancloud_app_id appKey: your_leancloud_app_key avatar: monsterid visitor: true
|
添加网站统计
位置: _config.butterfly.yml
1 2 3 4 5
| baidu_analytics: your_baidu_analytics_key
google_analytics: your_google_analytics_key
|
添加暗黑模式
位置: _config.butterfly.yml
1 2 3 4
| darkmode: enable: true button: true autoChangeMode: false
|
5.3 如何优化 SEO?
设置站点信息
位置: _config.yml
1 2 3 4 5 6
| title: 张宇的博客 subtitle: 记录学习、技术和生活 description: 一个用于记录学习笔记、技术实践和个人思考的简约博客。 keywords: 技术博客,学习笔记,Hexo,Butterfly author: 张宇 url: https://zhangyu10086.github.io
|
文章 SEO 优化
每篇文章添加完整的 Front Matter:
1 2 3 4 5 6 7 8 9 10 11
| --- title: 文章标题 # 标题要简洁有吸引力 date: 2026-07-20 10:00:00 categories: - 分类名 # 明确的分类 tags: - 标签1 # 相关的标签 - 标签2 description: 文章的简短描述,100字以内,包含关键词 # 重要! cover: /img/cover.jpg # 封面图 ---
|
生成 sitemap
安装插件:
1
| npm install hexo-generator-sitemap --save
|
配置: _config.yml
1 2
| sitemap: path: sitemap.xml
|
5.4 如何自定义页面布局?
创建自定义页面
1 2 3 4 5 6 7 8 9 10 11
| hexo new page links
--- title: 友情链接 date: 2026-07-20 type: links ---
页面内容...
|
添加到导航菜单
位置: _config.butterfly.yml
1 2 3 4 5
| menu: 首页: / || fas fa-home 归档: /archives/ || fas fa-archive 友链: /links/ || fas fa-link 关于: /about/ || fas fa-user
|
5.5 如何更换头像和封面?
更换头像
- 准备图片(建议 200x200 以上,PNG 或 JPG)
- 放到
source/img/ 目录
- 修改
_config.butterfly.yml:
1 2
| avatar: img: /img/my-avatar.png
|
更换默认封面
- 准备图片(建议 1200x675,比例 16:9)
- 放到
source/img/ 目录
- 修改
_config.butterfly.yml:
1 2 3 4 5
| cover: default_cover: - /img/cover1.jpg - /img/cover2.jpg - /img/cover3.jpg
|
为单篇文章设置封面
在文章的 Front Matter 中:
1 2 3 4
| --- title: 文章标题 cover: /img/custom-cover.jpg # 单独指定封面 ---
|
5.6 如何调整移动端样式?
位置: source/css/custom.css
在文件末尾的 @media (max-width: 768px) 区块内添加样式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| @media (max-width: 768px) { #recent-posts > .recent-post-item { border-radius: 10px; }
body { font-size: 14px; }
.layout { padding: 0 12px; } }
|
5.7 性能优化建议
图片优化
- 压缩图片:使用 TinyPNG 或 ImageOptim 压缩
- 合适尺寸:
- 头像:200x200
- 封面:1200x675
- 文章配图:800px 宽度
- WebP 格式:现代浏览器支持,体积更小
启用 CDN
位置: _config.butterfly.yml
1 2 3
| CDN: internal_provider: jsdelivr third_party_provider: jsdelivr
|
代码压缩
安装插件:
1
| npm install hexo-minify --save
|
会自动压缩 HTML、CSS、JS。
六、常见问题
Q1:修改配置后不生效?
解决方法:
1 2 3
| npm run clean npm run build npm run server
|
Q2:主题更新后配置丢失?
原因: 直接修改了 themes/butterfly/_config.yml
解决方法: 始终修改根目录的 _config.butterfly.yml,它会覆盖主题默认配置。
Q3:自定义 CSS 不生效?
检查项:
- 文件路径是否正确:
source/css/custom.css
- 是否在
_config.butterfly.yml 中注入:
1 2 3
| inject: head: - <link rel="stylesheet" href="/css/custom.css">
|
- 清理缓存后重新生成
Q4:部署后图片不显示?
原因: 图片路径错误
正确写法:
- Markdown 中:
 (开头要有 /)
- Front Matter 中:
cover: /img/cover.jpg
Q5:搜索功能不工作?
检查项:
package.json 中有 hexo-generator-search
_config.yml 中配置了搜索索引:
1 2
| search: path: search.xml
|
_config.butterfly.yml 中启用了本地搜索:
1 2 3 4
| search: use: local_search local_search: enable: true
|
- 构建后
public/search.xml 是否生成
七、总结
7.1 配置完成后的目录结构
1 2 3 4 5 6 7 8 9 10 11
| myblogs/ ├── _config.yml # ✅ 已配置:站点信息、搜索 ├── _config.butterfly.yml # ✅ 已配置:主题功能 ├── source/ │ ├── _posts/ # ✅ 2篇示例文章 │ ├── about/ # ✅ 关于页面 │ ├── img/ # ✅ 头像、封面图 │ ├── css/ # ✅ 自定义样式 │ └── js/ # ✅ 侧边栏搜索 ├── themes/butterfly/ # ✅ 主题已安装 └── public/ # ✅ 生成的静态网站(30个文件)
|
7.2 已实现的功能
- ✅ Butterfly 主题安装和配置
- ✅ 左侧侧边栏(头像、简介、社交链接、统计、最近文章/分类/标签)
- ✅ 中间文章卡片列表(带封面、摘要、hover动画)
- ✅ 本地搜索(顶部导航 + 侧边栏入口)
- ✅ 简约视觉风格(自定义CSS)
- ✅ 移动端响应式设计
- ✅ 关于页面
- ✅ 分类和标签页面
7.3 后续建议
- 内容为王:定期更新高质量文章
- SEO 优化:完善每篇文章的 Front Matter
- 功能扩展:根据需要添加评论、统计等功能
- 性能优化:图片压缩、CDN 加速
- 持续学习:关注 Butterfly 官方文档获取新特性
八、参考资料
文档更新日期:2026-07-20
博客版本:Hexo 8.1.2 + Butterfly 5.6.0
如有问题,欢迎在评论区留言或通过邮件联系我!