应用页与集成功能完整指南

分钟
应用页与集成功能完整指南
AI 概括

点击按钮,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.tsSiteConfig 添加 apps 数组类型 + pages.apps 开关
src/config/siteConfig.ts添加 pages.apps: trueapps 示例配置
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 配置:

astro.config.mjs
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 数组中添加:

astro.config.mjs
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 Action
  • scripts/submit-indexnow.mjs — CLI 提交脚本
  • package.json — 添加 submit-indexnow 命令

步骤 1:申请 IndexNow Key

  1. 访问 indexnow.org
  2. 生成一个 Key(一串随机字符串)
  3. 在你的网站根目录放置一个 {key}.txt 文件,内容为 Key 本身
    • 例如 Key 为 abc123,则创建 public/abc123.txt,内容为 abc123

步骤 2:配置 GitHub Secrets

在你的 GitHub 仓库中:

  1. 进入 Settings → Secrets and variables → Actions
  2. 点击 New repository secret
  3. Name: INDEXNOW_KEY
  4. Value: 你申请到的 Key

步骤 3:配置站点 URL

打开 src/pages/api/indexnow.ts,确认以下配置:

const baseUrl = "https://f3f3.top"; // ← 改为你的站点 URL

打开 scripts/submit-indexnow.mjs,确认:

const host = "f3f3.top"; // ← 改为你的站点域名

步骤 4:验证配置

Terminal window
# 本地测试(需要先构建)
pnpm build
pnpm submit-indexnow
# 强制提交所有 URL
curl -X POST https://你的域名/api/indexnow \
-H "Content-Type: application/json" \
-d '{"force": true}'

GitHub Action 工作流程

push 到 master 分支
自动触发 indexnow.yml
安装依赖 → 构建站点 → 恢复缓存 → 增量提交新 URL → 保存缓存

API 端点说明

端点方法说明
/api/indexnowPOST提交 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-05
pinned: true ← 添加这行
tags:
- 博客
category: 博客导航
---

效果

  • 置顶文章始终显示在文章列表最前面
  • 文章卡片和文章详情页显示 📌 置顶标记
  • 多篇置顶文章之间按发布日期排序

配置(已预设,无需修改):

  • 内容 Schema:src/content.config.tspinned: z.boolean().optional().default(false)
  • 排序逻辑:src/utils/content-utils.ts 中置顶文章优先
  • UI 组件:PostCard.astroPostMeta.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 数组中添加你的应用:

src/config/siteConfig.ts
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,
},
],

字段说明

字段类型必填说明
namestring应用名称
descriptionstring应用简介,支持 2 行截断
urlstring应用链接地址
imagestring应用图标 URL(支持网络图片和本地图片)
externalboolean是否外部链接(新标签页打开),默认 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 回退不生效?

  1. 确认 enable 已设为 true
  2. 确认 originalDomainfaviconDomain 填写正确
  3. 回退仅对 Markdown 内容中的 <img> 标签生效,不适用于 Astro <Image> 组件

Q: IndexNow 提交失败?

  1. 确认 GitHub Secrets 中已配置 INDEXNOW_KEY
  2. 确认网站根目录有 {key}.txt 文件且内容正确
  3. 检查 src/pages/api/indexnow.ts 中的站点 URL 是否正确
  4. IndexNow 支持的搜索引擎:Bing、Yandex、Naver、Seznam 等(不包括 Google)

Q: 应用页面图片显示异常?

  1. 网络图片需确保 URL 可访问
  2. 本地图片放在 public/ 目录下,以 / 开头引用
  3. 图片建议使用正方形(1:1 比例)以获得最佳显示效果

Q: 文章置顶不生效?

  1. 确认 frontmatter 中 pinned: true(注意是布尔值,不是字符串 "true"
  2. 确认文章未设置 draft: true(草稿不会显示在列表中)

七、版本信息

  • 集成日期:2026-06-05
  • 参考项目:Examplefuwari (Astro 5.x)
  • 适配版本:FireflyBlog 6.10.5 (Astro 6.3.5)
  • 构建验证:通过 ✅

支持与分享

如果这篇文章对你有帮助,欢迎分享给更多人或赞助支持!

赞助
应用页与集成功能完整指南
https://f3f3.top/posts/pa35354df/
作者
lyf
发布于
2026-06-05
许可协议
CC BY-NC-SA 4.0

评论区

Profile Image of the Author
lyf
Hello, I'm LyF.
公告
欢迎来到一飞的博客!。
音乐
封面

音乐

暂未播放

0:00 0:00
暂无歌词
分类
标签
站点统计
文章
13
分类
5
标签
16
总字数
46,038
运行时长
0
最后活动
0 天前

文章目录

🤖 AI 助手

👋 你好!

我可以帮你解答关于这篇文章的问题