echoes博客使用说明

快速开始

环境要求

  • Node.js 18+
  • pnpm

三步启动

代码块BASH · 3 行收起展开
git clone https://github.com/lsy2246/newechoes.git
cd echoes && pnpm i
pnpm run dev  # 访问 http://localhost:4321

快捷部署

Vercel

Deploy with Vercel

  • 构建命令:pnpm run build:vercel
  • 输出目录:dist
  • 后端目录:api/

Cloudflare Pages

  1. 打开 Cloudflare Dashboard,进入 Workers & Pages
  2. 选择 Create application -> Pages -> Import an existing Git repository
  3. 连接 GitHub,并选择 lsy2246/newechoes
  4. 构建命令填写:pnpm run build:cloudflare
  5. 构建输出目录填写:dist

如果你用本地 CLI 直传,命令是:

代码块BASH · 1 行收起展开
pnpm run deploy:cloudflare

EdgeOne Pages

EdgeOne 目前更适合直接通过控制台导入 Git 仓库快速部署。

  1. 打开 EdgeOne Pages,选择“导入 Git 仓库”
  2. 连接 GitHub,并选择 lsy2246/newechoes
  3. 构建命令填写:pnpm run build:edgeone
  4. 根目录填写:/

部署完成后,静态页面会从 dist/ 发布,后端函数会从 cloud-functions/api/ 自动识别。

参考文档:

部署说明

部署架构

当前项目统一采用这套结构:

  • 前端:Astro 输出纯静态文件到 dist/
  • 共享后端逻辑:src/server/api/
  • Vercel 函数入口:api/(构建生成)
  • Cloudflare Pages 函数入口:functions/api/(构建生成)
  • EdgeOne Cloud Functions 入口:cloud-functions/api/(构建生成)

也就是说,三个平台现在都是同一套思路:

  • 页面本身只输出静态文件
  • 搜索索引、文章页、列表页都来自静态产物
  • 豆瓣、微信读书、Git 项目、相册这些动态数据,通过各平台自己的函数目录接到同一份共享处理器上

这不是“某个平台单独走 SSR”,而是“统一静态前端 + 平台函数后端”。

Vercel

  • 构建命令:pnpm run build:vercel
  • 输出目录:dist
  • 函数目录:api/
  • 配置文件:vercel.json

api/ 由构建前的包装生成脚本输出,源码只保留在 src/server/api/

Cloudflare Pages

  • 构建命令:pnpm run build:cloudflare
  • 输出目录:dist
  • 函数目录:functions/api/
  • CLI 部署命令:pnpm run deploy:cloudflare

Cloudflare Pages 可以同时托管静态站点和 Pages Functions。
如果项目里有 functions/,函数文件必须放在仓库根目录,不能放进 dist/ 里。当前仓库会在构建或部署前自动生成这个目录。

EdgeOne Pages

  • 构建命令:pnpm run build:edgeone
  • 输出目录:dist
  • 函数目录:cloud-functions/api/
  • 配置文件:edgeone.json

EdgeOne Pages 也是静态前端和平台函数并存的模式。
它读取 dist/ 里的静态站点,同时读取仓库根目录下构建生成的 cloud-functions/edgeone.json

路由备注

文章页现在统一输出为 articles/*.html,不是旧的目录式 articles/*/index.html
如果后面再改平台路由或重写规则,这个点要保持一致。

核心功能

文章系统

创建文章(推荐方式):

代码块BASH · 1 行收起展开
pnpm new-post

运行后会进入交互模式:

  • 动态扫描 src/content 下现有目录
  • 先选择目标目录,默认使用当前目录
  • 再输入文章标题

也支持直接指定目录:

代码块BASH · 1 行收起展开
pnpm new-post "server/文章标题"

create_post.sh 已废弃,请使用 pnpm new-post。 也支持直接创建到根目录,例如 pnpm new-post "文章标题",但建议优先放到下面的场景目录里。

内容目录结构:

代码块TEXT · 8 行收起展开
src/content/
  ai/
  creator/
  dev/
  life/
  misc/
  server/
  system/

手动创建: 在合适的内容目录下创建 .md 文件

代码块MARKDOWN · 7 行收起展开
---
title: "文章标题"
date: 2026-05-29
tags: ["标签1", "标签2"]
---

文章内容...

title 是文章身份,也是文章 URL 的唯一来源。标题不能重复;移动文件、修改文件名或调整目录时,只要 title 不变,文章 URL 和历史归属就不会变化。

旧的文件路径详情页不会生成;文章正文里残留的旧链接只会被解析到新的标题地址,避免同时存在两套访问规则。

Markdown 写作能力

文章可以使用 .md.mdx 文件。普通文章建议先用 .md,需要在正文里直接引入 Astro/React 组件时再改用 MDX(.mdx)。

Frontmatter

每篇文章顶部需要写 frontmatter:

代码块MARKDOWN · 6 行收起展开
---
title: "文章标题"
date: 2026-05-29
tags: ["标签1", "标签2"]
summary: "可选摘要,会被搜索、RSS、列表页等功能使用"
---
  • title 必填,并且不能重复。
  • date 必填,用来表示发布时间。
  • tags 可选,用于筛选、索引和文章页展示。
  • summary 可选,适合放一句文章摘要。

Mermaid 图表

文章内置 Mermaid 图表支持。直接写 mermaid 代码块即可:

代码块MARKDOWN · 7 行收起展开
```mermaid
graph TD;
    A[开始] --> B[处理];
    B --> C{判断};
    C -->|通过| D[发布];
    C -->|退回| A;
```

构建时会把 Mermaid 代码块识别成图表容器,文章页只在检测到 Mermaid 时加载渲染脚本,页面切换后也会重新渲染。

代码块

普通代码块会使用 Shiki 高亮,并被增强成可折叠代码块,顶部会显示语言、行数和复制按钮:

代码块MARKDOWN · 5 行收起展开
```typescript
export function hello(name: string) {
  return `Hello, ${name}`;
}
```

没有语言时会按纯文本处理:

代码块MARKDOWN · 3 行收起展开
```text
这是一段纯文本示例
```

GFM 表格和任务列表

项目开启了 GFM,可以直接写表格、任务列表等常见 GitHub Markdown 语法。表格会自动包一层滚动容器,移动端不容易撑破页面。

代码块MARKDOWN · 8 行收起展开
| 功能 | 写法 |
| --- | --- |
| Mermaid 图表 | ` ```mermaid ` |
| 代码高亮 | ` ```typescript ` |
| 表格 | `| 标题 | 内容 |` |

- [x] 已完成
- [ ] 待处理

链接和引用

外链会自动添加 target="_blank"noopenernoreferrer 等属性。站内文章链接建议使用文章 URL,例如:

代码块MARKDOWN · 2 行收起展开
[查看文章列表](/articles)
[查看某篇文章](/articles/echoes博客使用说明)

如果文章标题保持不变,即使移动文件位置,系统也会尽量保持文章身份和历史记录稳定。

Git 修订历史

文章的发布时间来自 frontmatter 的 date。文章的最后更新时间和修订记录来自 Git 历史,不需要手写 updatedDate

  • 文件移动或改名时会优先通过 git log --follow 追踪
  • title 用来保证文章身份稳定,作为 Git rename 推断失败时的长期锚点
  • 文章页会展示 commit-like 的修订记录
  • 时间轴保留发布时间轴,并提供修订时间轴查看文章维护历史
代码块TYPESCRIPT · 3 行收起展开
export const SOURCE_REPOSITORY_CONFIG = {
  url: "",
};

不配置时,页面仍会读取本地 Git 历史,但不会生成提交或历史快照外链。GitHub、Gitee、GitLab、Bitbucket 等常见平台会根据 url 识别;自建 Gitea、Forgejo 或私有 GitLab 域名无法识别时,可以额外填写 provider: "gitea"provider: "forgejo"provider: "gitlab"

RSS 订阅

自动为所有文章生成 /rss.xml 订阅源,无需额外配置。

页面过渡与性能

  • View Transitions APISwup 实现流畅的无刷新切换
  • WebAssembly 优化前端数据处理性能
  • SEO 优化:自动生成元标签和站点地图
  • 响应式设计:自适应桌面和移动端

基础配置

编辑 src/consts.ts 配置网站必选信息:

代码块TYPESCRIPT · 19 行收起展开
export const SITE_META = {
  url: "https://your-domain.com",
  title: "你的网站名称",
  author: "作者名",
} as const;

// 导航结构
export const NAV_STRUCTURE = [
  { id: "home", text: "首页", href: "/" },
  {
    id: "articles",
    text: "文章",
    items: [
      { id: "filter", text: "筛选", href: "/filtered" },
      { id: "path", text: "网格", href: "/articles" },
    ],
  },
  { id: "albums", text: "相册", href: "/albums" },
];

可选功能模块

文章过期提醒

默认不启用。需要时从 src/consts.example.ts 复制这段可选配置到 src/consts.ts

代码块TYPESCRIPT · 5 行收起展开
export const ARTICLE_EXPIRY_CONFIG = {
  enabled: true,
  expiryDays: 365,
  warningMessage: "文章内容可能已过时",
};

项目展示

使用 @/components/GitProjects 展示 Git 平台项目:

代码块ASTRO · 6 行收起展开
<GitProjects
  platform={GitPlatform.GITHUB}
  username="your-username"
  title="我的项目"
  client:load
/>

豆瓣数据集成

使用 @/components/DoubanList 展示观影和读书记录:

代码块ASTRO · 4 行收起展开
// 观影记录
<DoubanList type="movie" title="看过的电影" doubanId="your-id" />
// 读书记录
<DoubanList type="book" title="读过的书" doubanId="your-id" />

相册瀑布流

相册页使用 Google Photos 分享链接作为数据源,并通过 @/components/PhotoAlbumMasonry 实现类似豆瓣页面的无限瀑布流加载。

页面示例:

代码块ASTRO · 9 行收起展开
---
import PhotoAlbumMasonry from "@/components/PhotoAlbumMasonry";
---

<PhotoAlbumMasonry
  shareId="your-share-id"
  title="我的相册"
  client:load
/>

从分享链接获取 ID:https://photos.app.goo.gl/your-share-id

相册数据来自 Google Photos 分享页内部接口,并非官方稳定 API。如果 Google 调整页面结构,可能需要同步适配。

微信读书书单

使用 @/components/WereadBookList 展示书单:

代码块ASTRO · 1 行收起展开
<WereadBookList listId="12345678" client:load />

从分享链接获取 ID:https://weread.qq.com/misc/booklist/12345678

旅行足迹

使用 @/components/WorldHeatmap 展示全球足迹:

代码块ASTRO · 4 行收起展开
<WorldHeatmap
  client:only="react"
  visitedPlaces={["中国-北京", "美国", "日本"]}
/>

故障排除

问题解决方案
图片显示问题确保图片放在 public 目录
豆瓣数据无法加载检查用户 ID,确认记录公开
相册无法加载检查 Google Photos 分享链接是否公开
Git 项目无法显示验证用户名和 API 访问权限
旅行足迹地球加载失败检查浏览器 WebAssembly 支持、CSP 设置与地图资源请求

历史版本

  1. 2aaee07 updated refactor component directory structure
  2. 4a8b1eb updated Refine public site template defaults
  3. c968a41 updated fix:修复vercel配置
  4. date published published

反向链接 0