博客迁移至 Astro:从零搭建现代化个人站点
为什么选择 Astro
Astro 是一个现代化的静态站点生成器,它的核心理念是 “Zero JavaScript by default”——默认情况下不向客户端发送任何 JavaScript,只在必要时按需加载。
与传统框架的对比
| 特性 | Astro | Next.js / Nuxt | Hexo / Hugo |
|---|---|---|---|
| 默认 JS 体积 | 0 KB | ~50-100 KB | 0 KB |
| 组件化 | ✅ 多框架支持 | ✅ 单一框架 | ❌ 模板引擎 |
| Markdown 原生支持 | ✅ 内容集合 | ✅ MDX | ✅ |
| 构建速度 | 快(Vite 驱动) | 中等 | 快 |
| 学习曲线 | 低 | 高 | 低 |
| 交互式组件 | 按需 Island | 全量 Hydration | 需额外集成 |
核心优势
1. Islands Architecture(群岛架构)
Astro 的群岛架构让你可以在静态页面中嵌入交互式组件。每个交互组件都是一个独立的 “岛”,互不干扰:
---
// 静态部分 —— 构建时渲染,零 JS
---
<StaticHeader />
<!-- 交互式搜索 —— 仅在客户端加载 JS -->
<SearchModal client:load />
<!-- 只在可见时加载的评论组件 -->
<Comment client:visible />
2. 内容集合(Content Collections)
Astro 提供类型安全的内容管理,通过 Zod schema 定义 frontmatter:
// src/content.config.ts
const blogCollection = defineCollection({
loader: glob({ base: './src/content/blog', pattern: '**/*.{md,mdx}' }),
schema: z.object({
title: z.string(),
description: z.string(),
pubDate: z.coerce.date(),
updatedDate: z.coerce.date().optional(),
tags: z.array(z.string()).default([]),
draft: z.boolean().default(false),
image: z.string().optional(),
video: z.string().optional(),
}),
});
3. 多框架兼容
同一个项目中可以混用 React、Vue、Svelte 组件,甚至纯 HTML/JS。
文章 Frontmatter 字段指南
每篇博客文章都是一个 Markdown(.md 或 .mdx)文件,存放在 src/content/blog/ 目录下。文件头部使用 YAML frontmatter 定义元数据。
完整字段说明
---
title: 文章标题 # 必填,显示在页面标题和列表中
description: 文章摘要 # 必填,用于 SEO description 和列表预览
pubDate: 2026-06-24 # 必填,发布日期
updatedDate: 2026-07-01 # 可选,最后更新日期
tags: [标签1, 标签2] # 可选,标签数组,用于分类和筛选
draft: false # 可选,true 时仅在开发环境可见
image: https://example.com/img # 可选,社交分享封面图
video: https://example.com/video # 可选,视频链接
---
字段详解
title(必填)
文章标题,会显示在:
- 博客首页文章卡片
- 文章详情页顶部
- 浏览器标签页标题
- RSS 订阅标题
title: 一篇关于 Astro 的深度解析
description(必填)
文章的简短描述,用于:
- SEO meta description
- 文章列表卡片中的摘要文字
- RSS 订阅摘要
- 社交分享时的描述
建议控制在 120-160 字以内。
description: 本文深入探讨 Astro 的群岛架构及其在现代 Web 开发中的优势
pubDate(必填)
发布日期,决定文章在列表中的排序(按日期倒序)。支持 YYYY-MM-DD 格式。
pubDate: 2026-06-24
updatedDate(可选)
文章最后更新日期。设置后会在文章页面显示”更新于 xxx”,方便读者了解内容的时效性。
updatedDate: 2026-07-15
tags(可选)
标签数组,用于文章分类。标签会显示在:
- 文章详情页标题下方
- 文章卡片底部
/tags标签聚合页- 每个标签的独立页面
/tags/[tag]
tags: [Astro, 前端, 博客]
draft(可选)
草稿标记,设为 true 后文章只在本地开发环境可见,生产构建时自动排除。默认为 false。
draft: true # 开发中,暂不发布
image(可选)
文章封面图 URL,用于 Open Graph 社交分享预览。
image: https://example.com/cover.png
video(可选)
文章关联视频链接。
video: https://www.youtube.com/watch?v=xxx
文件命名规范
推荐使用 YYYY-MM-DD-slug.md 格式:
src/content/blog/
├── 2026-06-24-astro-blog-migration.md
├── 2026-06-15-nas-setup.md
└── 2026-06-01-neovim-setup.md
这样既能在文件系统中按日期排序,也有语义化的 URL slug。
博客功能一览
本博客在迁移到 Astro 的过程中,逐步实现了以下特性:
内容与排版
- Markdown / MDX 渲染 — 支持标准 Markdown 语法及 MDX 内嵌组件
- 代码语法高亮 — 基于 Shiki,支持亮/暗双主题
- 代码块一键复制 — 悬浮在代码块右上角的复制按钮
- 自动目录(TOC) — 桌面端右侧固定目录,根据 h2/h3 标题自动生成
导航与浏览
- 浮动快捷按钮 — 返回上一页、回到顶部、跳到底部
- 文章分页 — 首页和归档页的分页浏览
- 上一篇 / 下一篇导航 — 文章底部的前后文章跳转
- 标签系统 — 标签云 + 标签聚合页 + 按标签筛选
搜索与发现
- 全文搜索 — 基于 Pagefind 的静态搜索,构建时生成索引
- RSS 订阅 — 自动生成 RSS 2.0 源
- Open Graph 元数据 — 社交分享时的标题、描述、封面图
视觉与体验
- 暗色 / 亮色主题 — 默认暗色,一键切换
- 中英文双语 — 界面文字支持中文 / 英文切换
- 响应式布局 — 桌面端三栏(个人信息 + 内容 + 目录),手机端自适应
- 几何低多边形背景 — 装饰性背景图案
- GitHub 贡献热力图 — 左侧信息栏集成 GitHub 活跃度
互动与社交
- 评论系统 — 集成 Giscus(基于 GitHub Discussions)
- 友链页面 — 支持头像、描述的好友链接展示
- 个人信息卡片 — 头像、简介、社交链接
开发体验
- TypeScript 支持 — 全链路类型安全
- Vite 开发服务器 — 毫秒级热更新
- 内容集合类型推断 — frontmatter 字段自动补全和校验
- 草稿模式 —
draft: true仅在开发环境可见
快速上手:写一篇新文章
# 1. 在 src/content/blog/ 下创建新文件
touch src/content/blog/2026-06-24-my-post.md
# 2. 填写 frontmatter
# 3. 编写正文内容
# 4. 本地预览
npm run dev
# 5. 构建发布
npm run build
就这么简单——Astro 会自动识别新文件,生成对应的路由页面和 RSS 条目。
总结
Astro 的核心理念与个人博客场景天然契合:大部分内容都是静态的,只有少数几个交互组件需要 JavaScript。群岛架构让我们可以为每个交互组件精确控制加载时机(client:load、client:visible、client:idle),避免不必要的 JS 开销。
内容集合机制则让 Markdown 写作获得了类型安全保障——frontmatter 字段缺失或类型错误在构建时就能被发现,而不是发布后才发现页面显示异常。
如果你也在考虑博客框架选型,Astro 值得一试。