技术日志 2026.04.18

用 Astro + Cloudflare 搭建个人博客:完整技术指南

这篇文章是本博客的完整技术文档,记录了从选型到部署的全部细节,方便日后维护或交接给新同事。

项目概述

这是一个个人技术博客,内容聚焦于 WordPress 建站、OxygenBuilder、Hugo 部署、Cloudflare 配置等实践经验。

  • 视觉主题:简洁现代,浅色背景 + Indigo 蓝紫色调
  • 首页:深色渐变 Hero 区域(slate-950 → indigo-950)+ 极致极简无边框序列列表(Borderless Minimalist Row List)
  • 字体:Inter(正文)+ JetBrains Mono(代码块),通过 Google Fonts 加载
  • 文章代码块:GitHub Dark Dimmed 主题 + macOS 三点装饰 + 复制按钮 + Lightbox 图片预览

技术栈选型

层级技术版本
框架Astro^6.1.7
CSSTailwind CSS^4.2.2
UI KitDaisyUI^5.5.19
语法高亮Shiki(Astro 内置)
部署适配器@astrojs/cloudflare^13.1.10
SEO@astrojs/sitemap^3.7.2
部署工具Wrangler^4.83.0

为什么选 Astro?内容型网站的理想框架:默认输出纯静态 HTML,构建速度极快,Shiki 语法高亮开箱即用,Cloudflare 适配器一行配置完成部署。

目录结构

项目的完整文件树如下,每个目录有其明确职责:

latest/
├── astro.config.mjs     核心配置(site 域名、output、sitemap、Shiki 主题)
├── package.json         依赖清单
├── wrangler.jsonc       Cloudflare Workers 部署配置
├── public/              静态资源(原样发布,不经过编译)
│   ├── pic/             博客文章图片(全部本地化)
│   ├── og-default.png   OG 默认封面图(1200×630)
│   ├── robots.txt       爬虫协议
│   └── llms.txt         AI 搜索引擎上下文
└── src/
    ├── components/      可复用 UI 组件
    │   ├── Header.astro
    │   ├── Footer.astro
    │   └── SeoHead.astro  ← SEO 核心,注入所有 meta 标签
    ├── layouts/
    │   └── BaseLayout.astro
    ├── pages/           路由文件
    │   ├── index.astro          → /
    │   ├── about.astro          → /about/
    │   ├── archives/[...slug]   → /archives/文章ID/
    │   └── tags/[tag]           → /tags/标签/
    ├── content/blog/    Markdown 文章(动态持续更新)
    └── styles/global.css

内容管理规范

文章 Frontmatter 规范

每篇文章的 .md 文件顶部必须包含以下字段:

---
title: "文章标题"
pubDate: 2026-04-18 15:30:00       # 必填,带精确完整的时分秒以严格控制文章先后主序
description: "80-150字摘要,直接作为 Google 搜索结果描述显示"
tags: ['WordPress', 'Cloudflare']   # 可选,大小写敏感
---

请保持标签规范统一。为了确保 URL 链接完全呈纯英文字母以提升 SEO 与分析质量,全站已内置中英 URL 智能转换机制:前台会保留优美的中文标签(如:# 个人博客),但在底层路由(src/utils.ts)命中字典,自动生成纯英文归档地址(如 /tags/personal-blog/)。

未来如果新增纯中文的新标签想要英文 URL 去重,只需前往 src/utils.tstagSlugMap 字典增加一行对应字典即可。

我们已为该项目沉淀了 AI 全自动发布工作流(详见项目根目录下的 AI发布文章指南.md 或博文《让 AI 帮你发布博客文章》),操作变得极度简单:

  1. 把原始笔记/草稿直接丢给大模型并输入:“帮我发布这篇文章”。
  2. 大模型会自动按照架构为你生成极其规范的中文 titledescription 以及纯英文小写连字符的文件名。
  3. 确认无误后,AI 会自动排版并写入 src/content/blog/
  4. 通过一句 npm run deploy 全球极速发布。

图片管理

  • 所有文章图片统一放在 public/pic/
  • 图片点击会触发 Lightbox 浮层预览,不会跳转离开页面
  • public/ 目录的文件不经过 Astro 编译,构建后原样复制到 dist/

SEO 架构设计

全局配置

// astro.config.mjs
export default defineConfig({
  site: 'https://oneuie.me',   // sitemap 和 canonical URL 的基础域名
  output: 'static',           // 静态预渲染
  integrations: [sitemap()],  // 构建时自动生成 /sitemap-index.xml
  adapter: cloudflare(),
})

SeoHead 组件注入的标签

每个页面通过 BaseLayout → SeoHead 自动注入:

  • <title><meta name="description">
  • <link rel="canonical">(防止重复内容降权)
  • Open Graph 标签(微信/Facebook 分享预览)
  • Twitter Card(summary_large_image)
  • JSON-LD 结构化数据(Google 富结果)
  • robots: index, follow, max-image-preview:large

各页面 SEO 配置

页面og:typeJSON-LD
首页 /websiteWebSite
文章 /archives/[slug]/articleBlogPosting
归档 / 标签 / 关于websiteWebSite

文章页会额外输出 article:published_timearticle:tag 和完整 BlogPosting schema(含 headline / datePublished / author / keywords)。

爬虫与 AI 引导文件

  • /sitemap-index.xml:构建时自动首发。其使用了标准 Google 命名空间与分块化地图索引(sitemapindex -> sitemap-0.xml)的技术最佳实践。只需要把由于向搜索引擎提交此 Index 后缀即可。
  • /robots.txt:允许所有爬虫 + 指向 sitemap
  • /llms.txt:为 ChatGPT / Claude / Perplexity 等 AI 搜索提供结构化上下文
  • /og-default.png:1200×630 默认封面图,用于无封面图的页面分享

部署流程

npm run dev        # 本地开发(热更新)
npx astro build && npx wrangler dev      # 构建生产包(生成 dist/ 和 sitemap)
npx astro build && npx wrangler deploy     # 构建 + 推送到 Cloudflare(一键完成)

npm run deploy 等同于 astro build && wrangler deploy,无需手动 git push。

图片优化方案

当前图片全部为 JPG 格式,推荐以下方案转换为 WebP:

  • Cloudflare Polish(推荐):Dashboard → Speed → Optimization → Polish → Lossy + WebP。零代码,CDN 层自动转换。
  • 本地批量转换brew install webp 后运行 cwebp -q 82 input.jpg -o output.webp

注意:Astro 的 <Image> 组件(来自 astro:assets)只对 .astro/.mdx 文件中的图片生效,对 .md 中的原始 <img> 标签无效。

常见问题

Q:运行本地构建报错 `[WARN] Missing pages directory: src/pages` 并导致后续挂掉?
A:这是因为你在终端站错文件夹了。系统错把你上一级的 `Projects` 文件夹当成了代码库,所以找不到里面的页面。运行报错时,请先敲击 `cd latest` 回车进入正确的代码根目录,然后再敲构建命令。

Q:同一天发布的多篇文章在首页排序前后错乱、互相争抢第一?
A:这是因为文章头部的 pubDate 仅仅写了日期(如 2026-04-18),系统会统一默认它们都是该天的 00:00:00,因为毫秒数完全一致,Astro 排序算法将随机分发先后。唯一的解决办法是加上精确到秒的当前时间(如 2026-04-18 15:30:00),从而利用 Astro 原生底层的日期机制严格执行时分秒精度降序排列。

Q:新增文章后首页没有显示?
A:检查 pubDate 格式是否遵循上述规范,并重新运行 npm run dev

Q:代码块没有语法高亮?
A:在代码围栏后加语言名,如 ```javascript 而不是单独的 ```

Q:图片点击直接跳转而不是 Lightbox?
A:图片需被 <a href="/pic/xxx.jpg"> 包裹,Lightbox 只在文章详情页生效。

Q:如何切换代码块 Shiki 主题?
A:在 astro.config.mjsmarkdown.shikiConfig.theme 修改,可选主题见 shiki.style/themes

参考文档