从零搭建Astro博客并部署到Netlify
去年折腾了一圈 Hugo 和 Hexo,最后还是回到了 Astro。原因很简单:Lighthouse 性能分数从 62 分涨到了 98 分。
本文记录我从零搭建 Astro 博客并部署到 Netlify 的全过程。
Astro 是什么
Astro 是个静态网站生成器,核心就两个特点:
- 零 JS 运行时:默认生成纯 HTML + CSS
- 孤岛架构:只有需要交互的组件才加载 JavaScript
这意味着什么?你的博客文章页面只会渲染 HTML 和 CSS,除非你自己加了交互组件。我之前用 Next.js 写博客,Lighthouse 性能分数一直在 60-70 分徘徊,换成 Astro 后直接干到 98 分。
框架无关也是个亮点。React、Vue、Svelte 都能混着用,或者干脆纯 HTML。我的博客主站用纯 Astro,后台管理页面用了 React,各司其职。
准备工作
你需要这些东西:
- Node.js 18.14.1 或更高版本
- npm/yarn/pnpm 任选一个
- Git
- 代码编辑器(VS Code 就行)
基础知识:HTML、CSS、JavaScript 基础,Markdown 语法,Git 基本操作。
创建 Astro 项目
两种方式,看你时间紧不紧。
方式一:从脚手架开始
npm create astro@latest my-blog按照提示选就行:
- 模板选 “blog” 或 “blank”
- TypeScript 推荐选 “严格” 模式
- 其他一路回车
方式二:直接用博客模板
npm create astro@latest my-blog -- --template blog这个会自带一堆示例配置,适合想快速上手的。
项目结构
创建完成后你会看到这样的目录:
my-blog/├── public/ # 静态资源│ ├── favicon.svg│ └── images/├── src/ # 源码│ ├── components/ # 组件│ ├── content/ # 内容│ │ └── posts/ # 博客文章│ ├── layouts/ # 布局│ ├── pages/ # 页面(文件即路由)│ └── styles/ # 样式├── astro.config.mjs # 配置文件└── package.json几个关键目录:
- src/pages/:文件即路由,
src/pages/about.astro就是/about - src/content/:放博客文章的地方,支持 Content Collections
- src/components/:可复用组件
- src/layouts/:页面布局模板
- public/:静态资源,原封不动复制到输出目录
基础配置
编辑 astro.config.mjs:
import { defineConfig } from 'astro/config';import mdx from '@astrojs/mdx';import sitemap from '@astrojs/sitemap';import tailwind from '@astrojs/tailwind';
export default defineConfig({ site: 'https://your-blog.netlify.app', integrations: [ mdx(), sitemap(), tailwind(), ], markdown: { shikiConfig: { theme: 'github-dark', wrap: true } }});site 字段记得改成你的域名,不然 sitemap 会生成错。
Content Collections 配置
Astro 推荐用 Content Collections 管理内容。在 src/content/config.ts 定义 schema:
import { defineCollection, z } from 'astro:content';
const blog = defineCollection({ type: 'content', schema: z.object({ title: z.string(), description: z.string(), publishDate: z.coerce.date(), updatedDate: z.coerce.date().optional(), heroImage: z.string().optional(), tags: z.array(z.string()).default([]), draft: z.boolean().default(false), }),});
export const collections = { blog };这样写文章时 frontmatter 格式不对,构建会直接报错。我刚开始没加 schema,写了篇文章把 publishDate 写成 date,跑到线上才发现 404。
写第一篇文章
在 src/content/blog/ 创建 first-post.md:
---title: '我的第一篇博客文章'description: '欢迎来到我使用Astro搭建的博客!'publishDate: '2025-08-30'tags: ['astro', '博客', '入门']---
# 欢迎来到我的博客
这是我使用 Astro 框架搭建的第一篇博客文章。
## Astro 的优势
- 超快的页面加载速度- 优秀的 SEO 性能- 现代化的开发体验创建页面布局
在 src/layouts/BlogLayout.astro 创建博客布局:
---export interface Props { title: string; description?: string;}
const { title, description } = Astro.props;---
<!DOCTYPE html><html lang="zh-CN"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>{title}</title> {description && <meta name="description" content={description} />} <link rel="icon" type="image/svg+xml" href="/favicon.svg" /> </head> <body> <header> <nav> <a href="/">首页</a> <a href="/blog">博客</a> <a href="/about">关于</a> </nav> </header>
<main> <slot /> </main>
<footer> <p>© 2025 我的博客. All rights reserved.</p> </footer> </body></html>添加 RSS 订阅
安装插件:
npm install @astrojs/rss创建 src/pages/rss.xml.js:
import rss from '@astrojs/rss';import { getCollection } from 'astro:content';
export async function GET(context) { const posts = await getCollection('blog');
return rss({ title: '我的博客', description: '分享技术和生活的点点滴滴', site: context.site, items: posts.map((post) => ({ title: post.data.title, pubDate: post.data.publishDate, description: post.data.description, link: `/blog/${post.slug}/`, })), });}添加搜索功能
用 Pagefind,免费且支持中文。
npm install pagefind在 package.json 修改构建命令:
{ "scripts": { "build": "astro build && pagefind --site dist" }}SEO 优化
创建 src/components/SEOHead.astro:
---export interface Props { title: string; description: string; image?: string; type?: 'website' | 'article';}
const { title, description, image, type = 'website' } = Astro.props;const canonicalURL = new URL(Astro.url.pathname, Astro.site);const socialImage = image ? new URL(image, Astro.site) : null;---
<!-- 基础 SEO 标签 --><meta name="description" content={description} /><link rel="canonical" href={canonicalURL} />
<!-- Open Graph --><meta property="og:type" content={type} /><meta property="og:title" content={title} /><meta property="og:description" content={description} /><meta property="og:url" content={canonicalURL} />{socialImage && <meta property="og:image" content={socialImage} />}
<!-- Twitter Cards --><meta name="twitter:card" content="summary_large_image" /><meta name="twitter:title" content={title} /><meta name="twitter:description" content={description} />{socialImage && <meta name="twitter:image" content={socialImage} />}本地开发
npm run dev访问 http://localhost:4321。
构建生产版本:
npm run build生成的静态文件在 dist/ 目录。
预览构建结果:
npm run preview部署到 Netlify
Git 集成部署(推荐)
创建 Git 仓库并推送到 GitHub:
git initgit add .git commit -m "Initial commit"git remote add origin https://github.com/your-username/your-blog.gitgit push -u origin main登录 Netlify:
- 点击 “New site from Git”
- 连接你的 GitHub 账户
- 选择博客仓库
- 配置构建设置:
- Build command:
npm run build - Publish directory:
dist - Node version: 18
- Build command:
推送代码后 Netlify 会自动构建部署。
CLI 部署
安装 Netlify CLI:
npm install -g netlify-cli登录并部署:
netlify loginnetlify initnetlify deploy --prod环境变量和自定义域名
环境变量在 Netlify 控制台的 Site Settings > Environment Variables 添加。
自定义域名在 Domain Settings 配置,HTTPS 会自动启用。
性能优化建议
图片优化:
- 使用 WebP 格式
- 实施懒加载
- 响应式图片
代码分割:
- 按需加载 JavaScript
- 优化 CSS bundle 大小
CDN 优化:
- Netlify 自带 CDN
- 配置缓存策略
监控与分析
Google Analytics 集成:
<script async src="https://www.googletagmanager.com/gtag/js?id=GA_ID"></script><script> window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'GA_ID');</script>性能监控用 Lighthouse,关注 Core Web Vitals 指标。
常见问题
构建失败?
- 检查 Node.js 版本
- 清除缓存:
rm -rf node_modules package-lock.json && npm install - 检查 markdown 文件的 frontmatter 格式
- 看构建日志的具体错误
样式问题?
- 确保 CSS 文件正确导入
- 检查 Tailwind CSS 配置
- 验证组件作用域样式
部署问题?
- 确认构建命令和发布目录
- 检查环境变量
- 验证依赖项是否完整安装
扩展功能
评论系统可以集成 Giscus(基于 GitHub Discussions)或 Utterances(基于 GitHub Issues)。
内容管理考虑 Decap CMS(原 Netlify CMS)或 Sanity。
多语言支持在 astro.config.mjs 配置:
export default defineConfig({ i18n: { defaultLocale: "zh-cn", locales: ["zh-cn", "en"], }});我的踩坑记录
第一次部署时忘记设置 site 字段,sitemap 生成的全是相对路径,搜索引擎抓不到。改完重新部署就好了。
还有一次 Content Collections schema 写错了,publishDate 应该是 z.coerce.date(),我写成了 z.date(),结果日期格式一直不对,搞了半天才发现问题在哪。
图片优化踩的坑更多。一开始直接用高分辨率图片,Lighthouse 性能分数只有 80 分。后来改用 WebP + 懒加载,才干到 98 分。
Astro 的开发体验确实不错,但配置文件一开始会花点时间。建议从官方博客模板开始,然后慢慢改。
记住:博客是拿来写内容的,别一直折腾配置。能用就行,写作才是重点。
推荐文章
基于标签匹配 · 智能推荐支持与分享
如果这篇文章对你有帮助,欢迎分享给更多人或赞助支持!
喵斯基部落