应用页与集成功能完整指南
点击按钮,AI 将为你生成这篇文章的摘要
本文档详细记录了从 Examplefuwari 项目集成到 FireflyBlog 的四大功能,包含完整的文件清单、配置方法和使用说明。
一、功能总览
本次集成共涉及以下功能,所有改动均不改变原有代码结构:
| 功能 | 类型 | 风险等级 | 说明 |
|---|---|---|---|
| 双 CDN 图床回退 | 新增插件 | 低 | 主力图床失效时自动切换备用图床 |
| 图片懒加载 | 新增插件 | 低 | Markdown 图片自动添加 loading=“lazy” |
| IndexNow | 新增 API + Action + 脚本 | 低 | 一键推送新内容至搜索引擎 |
| 文章置顶 | 已有功能 | 无 | 前端已完整实现,无需修改 |
| 应用中心 | 新增页面 | 低 | 展示个人应用、工具和服务链接 |
二、新增文件清单
FireflyBlog/├── src/│ ├── plugins/│ │ ├── rehype-image-fallback.mjs ← 双 CDN 图床回退插件│ │ └── rehype-image-attrs.mjs ← 图片懒加载插件│ ├── pages/│ │ ├── apps.astro ← 应用中心页面│ │ └── api/│ │ └── indexnow.ts ← IndexNow API 端点├── .github/│ └── workflows/│ └── indexnow.yml ← IndexNow GitHub Action├── scripts/│ └── submit-indexnow.mjs ← IndexNow CLI 提交脚本三、修改文件清单
| 文件 | 改动内容 |
|---|---|
astro.config.mjs | 添加两个 rehype 插件导入 + 配置 + sitemap 过滤 |
src/types/config.ts | SiteConfig 添加 apps 数组类型 + pages.apps 开关 |
src/config/siteConfig.ts | 添加 pages.apps: true 和 apps 示例配置 |
src/config/navBarConfig.ts | ”关于”子菜单添加”应用”导航项 |
package.json | 添加 submit-indexnow 脚本 |
四、功能详解与使用方法
4.1 双 CDN 图床回退
原理:通过 rehype 插件在 Markdown 渲染时为所有来自主力图床的 <img> 标签添加 onerror 属性,当图片加载失败时自动切换到备用图床。
文件:src/plugins/rehype-image-fallback.mjs
配置方法:
打开 astro.config.mjs,找到 rehypePlugins 数组末尾的 rehypeImageFallback 配置:
import rehypeImageFallback from "./src/plugins/rehype-image-fallback.mjs";
// 在 rehypePlugins 数组中:[ rehypeImageFallback, { enable: true, // ← 改为 true 启用 originalDomain: "你的主力图床域名", // 例如 "images.example.com" fallbackDomain: "你的备用图床域名", // 例如 "backup.example.com" },],配置示例:
// 假设主力图床是 images.mysite.com,备用是 backup.r2.dev[ rehypeImageFallback, { enable: true, originalDomain: "images.mysite.com", fallbackDomain: "backup.r2.dev", },],工作流程:
文章图片: https://images.mysite.com/photo.webp ↓ 加载失败触发 onerror自动切换: https://backup.r2.dev/photo.webp注意事项:
- 仅对 Markdown 内容中的图片生效,不影响 Astro
<Image>组件 - 主力和备用图床的文件路径结构必须一致
- 默认关闭(
enable: false),需手动开启
4.2 图片懒加载
原理:通过 rehype 插件为 Markdown 渲染输出中所有 <img> 标签自动添加 loading="lazy" 和 decoding="async" 属性,实现原生懒加载。
文件:src/plugins/rehype-image-attrs.mjs
配置方法:
打开 astro.config.mjs,在 rehypePlugins 数组中添加:
import rehypeImageAttrs from "./src/plugins/rehype-image-attrs.mjs";
// 在 rehypePlugins 数组中(建议放在 rehypeImageFallback 之前):rehypeImageAttrs,效果:
<!-- 渲染前 --><img src="photo.webp" alt="风景">
<!-- 渲染后(自动添加) --><img src="photo.webp" alt="风景" loading="lazy" decoding="async">注意事项:
- 仅在属性未设置时才添加,不会覆盖已有属性
- 不设置
fetchpriority,避免影响 LCP(最大内容绘制)图片 - 与
ImageWrapper组件的loading="lazy"互不冲突
4.3 IndexNow 集成
原理:IndexNow 是一个即时索引协议,允许网站主动通知搜索引擎(Bing、Yandex、Naver 等)内容已更新,加速搜索引擎收录。
涉及文件:
src/pages/api/indexnow.ts— API 端点.github/workflows/indexnow.yml— GitHub Actionscripts/submit-indexnow.mjs— CLI 提交脚本package.json— 添加submit-indexnow命令
步骤 1:申请 IndexNow Key
- 访问 indexnow.org
- 生成一个 Key(一串随机字符串)
- 在你的网站根目录放置一个
{key}.txt文件,内容为 Key 本身- 例如 Key 为
abc123,则创建public/abc123.txt,内容为abc123
- 例如 Key 为
步骤 2:配置 GitHub Secrets
在你的 GitHub 仓库中:
- 进入 Settings → Secrets and variables → Actions
- 点击 New repository secret
- Name:
INDEXNOW_KEY - Value: 你申请到的 Key
步骤 3:配置站点 URL
打开 src/pages/api/indexnow.ts,确认以下配置:
const baseUrl = "https://f3f3.top"; // ← 改为你的站点 URL打开 scripts/submit-indexnow.mjs,确认:
const host = "f3f3.top"; // ← 改为你的站点域名步骤 4:验证配置
# 本地测试(需要先构建)pnpm buildpnpm submit-indexnow
# 强制提交所有 URLcurl -X POST https://你的域名/api/indexnow \ -H "Content-Type: application/json" \ -d '{"force": true}'GitHub Action 工作流程
push 到 master 分支 ↓自动触发 indexnow.yml ↓安装依赖 → 构建站点 → 恢复缓存 → 增量提交新 URL → 保存缓存API 端点说明
| 端点 | 方法 | 说明 |
|---|---|---|
/api/indexnow | POST | 提交 URL 到 IndexNow |
请求体:
{ "force": false // true=强制提交所有URL,false=仅提交新增URL}响应示例:
{ "success": true, "message": "URLs submitted to IndexNow successfully (incremental mode)", "totalUrls": 5, "newUrls": 2, "isIncremental": true}4.4 文章置顶
状态:FireflyBlog 已完整实现,无需额外操作。
使用方法:
在文章的 frontmatter 中添加 pinned: true:
---title: 我的置顶文章published: 2026-06-05pinned: true ← 添加这行tags: - 博客category: 博客导航---效果:
- 置顶文章始终显示在文章列表最前面
- 文章卡片和文章详情页显示 📌 置顶标记
- 多篇置顶文章之间按发布日期排序
配置(已预设,无需修改):
- 内容 Schema:
src/content.config.ts中pinned: z.boolean().optional().default(false) - 排序逻辑:
src/utils/content-utils.ts中置顶文章优先 - UI 组件:
PostCard.astro和PostMeta.astro显示置顶标记
4.5 应用中心页面
原理:新增 /apps/ 页面,以网格卡片形式展示个人应用、工具和服务链接。
文件:
src/pages/apps.astro— 页面组件src/config/siteConfig.ts— 应用数据配置src/types/config.ts— 类型定义src/config/navBarConfig.ts— 导航栏配置
步骤 1:添加应用数据
打开 src/config/siteConfig.ts,在 apps 数组中添加你的应用:
apps: [ { name: "ChatGPT", description: "AI 对话助手,支持多模态交互", url: "https://chat.openai.com", image: "https://cdn.oaistatic.com/images/favicon-o.svg", external: true, }, { name: "Claude", description: "Anthropic 出品的 AI 助手", url: "https://claude.ai", image: "https://claude.ai/images/branding/claude-logo.svg", external: true, }, { name: "我的工具站", description: "自研在线工具集合", url: "/tools/", image: "/assets/images/tools-icon.webp", external: false, },],字段说明
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
name | string | 是 | 应用名称 |
description | string | 否 | 应用简介,支持 2 行截断 |
url | string | 是 | 应用链接地址 |
image | string | 是 | 应用图标 URL(支持网络图片和本地图片) |
external | boolean | 否 | 是否外部链接(新标签页打开),默认 false |
步骤 2:页面开关
在 siteConfig.ts 中控制页面是否启用:
pages: { // ...其他配置 apps: true, // true=显示,false=隐藏},关闭后:
- 访问
/apps/返回 404 - 导航栏不再显示”应用”入口
- 不出现在 sitemap 中
步骤 3:导航栏位置
默认在”关于”子菜单中。如需修改位置,编辑 src/config/navBarConfig.ts:
// 默认位置:关于 → 应用links.push({ name: "关于", url: "/about/", children: [ LinkPreset.About, ...(siteConfig.pages.friends ? [LinkPreset.Friends] : []), ...(siteConfig.pages.sponsor ? [LinkPreset.Sponsor] : []), ...(siteConfig.pages.apps ? [{ name: "应用", url: "/apps/", icon: "material-symbols:apps", }] : []), ],});
// 如果想放在"动态"子菜单下,将上面的代码移到"动态"的 children 中即可五、配置速查表
astro.config.mjs 完整改动
// ===== 新增导入 =====import rehypeImageAttrs from "./src/plugins/rehype-image-attrs.mjs";import rehypeImageFallback from "./src/plugins/rehype-image-fallback.mjs";
// ===== rehypePlugins 数组末尾添加 =====rehypeImageAttrs,[ rehypeImageFallback, { enable: false, // 改为 true 启用双 CDN 回退 originalDomain: "", // 填写主力图床域名 fallbackDomain: "", // 填写备用图床域名 },],
// ===== sitemap filter 中添加 =====if (pathname === "/apps/" && !siteConfig.pages.apps) { return false;}siteConfig.ts 完整改动
// ===== pages 对象中添加 =====pages: { // ...已有配置 apps: true, // 应用中心页面开关},
// ===== 对象末尾添加(在 lang 之后) =====apps: [ { name: "应用名称", description: "应用描述", url: "https://example.com", image: "https://example.com/icon.png", external: true, },],六、常见问题
Q: 双 CDN 回退不生效?
- 确认
enable已设为true - 确认
originalDomain和faviconDomain填写正确 - 回退仅对 Markdown 内容中的
<img>标签生效,不适用于 Astro<Image>组件
Q: IndexNow 提交失败?
- 确认 GitHub Secrets 中已配置
INDEXNOW_KEY - 确认网站根目录有
{key}.txt文件且内容正确 - 检查
src/pages/api/indexnow.ts中的站点 URL 是否正确 - IndexNow 支持的搜索引擎:Bing、Yandex、Naver、Seznam 等(不包括 Google)
Q: 应用页面图片显示异常?
- 网络图片需确保 URL 可访问
- 本地图片放在
public/目录下,以/开头引用 - 图片建议使用正方形(1:1 比例)以获得最佳显示效果
Q: 文章置顶不生效?
- 确认 frontmatter 中
pinned: true(注意是布尔值,不是字符串"true") - 确认文章未设置
draft: true(草稿不会显示在列表中)
七、版本信息
- 集成日期:2026-06-05
- 参考项目:Examplefuwari (Astro 5.x)
- 适配版本:FireflyBlog 6.10.5 (Astro 6.3.5)
- 构建验证:通过 ✅
支持与分享
如果这篇文章对你有帮助,欢迎分享给更多人或赞助支持!