博客系统

博客是网站的核心内容功能,支持文章列表、详情页面、分类与标签筛选以及富文本内容渲染。

博客列表

路由: /[locale]/blog

以分页列表形式展示文章(每页 5 篇),右侧边栏包含分类和标签筛选器。

每篇文章渲染为一个 ArticleCard,包含:

  • 封面图片(无图时回退为 SVG 占位图)

  • 分类链接(点击跳转至分类筛选页面)

  • 发布日期

  • 标题(链接到文章详情页;通过 ::after 伪元素覆盖层实现整个卡片可点击)

  • 摘要(最多显示 3 行)

  • 标签胶囊(链接到标签筛选页,绿色背景,悬停时加深)

文章详情

路由: /[locale]/blog/[slug]

渲染完整文章,包含以下内容:

  • 头部:分类 + 日期元信息行、标题、作者姓名

  • 正文:富 Markdown 内容(通过 RichMarkdown 组件渲染)

  • 标签:正文下方的胶囊链接

  • 右侧边栏:分享按钮、复制链接按钮

  • 底部的u201c联系我们u201d按钮

分类视图

路由: /[locale]/blog/categories/[categorySlug]

使用 CategoryArticleViewer 组件,采用三栏布局:

  • 左侧边栏 --- 文章标题列表(可点击按钮,最多显示 3 行)。点击标题后在中间面板加载文章并滚动到顶部。

  • 中间区域 --- 完整文章内容,支持富 Markdown 渲染。标题链接到独立的文章详情页面。

  • 右侧边栏 --- 目录(滚动监听高亮当前标题)

该分类下的所有文章一次性加载(最多 100 篇)。查看器支持 Mermaid 图表、KaTeX 数学公式、YouTube 嵌入和原始 HTML。

标签筛选

路由: /[locale]/blog/tags/[tagSlug]

布局与博客主列表相同,但仅显示包含指定标签的文章。每页 5 篇。

富 Markdown 渲染

RichMarkdown 组件(src/components/RichMarkdown.tsx)封装了 react-markdown,并集成了以下插件:

插件

功能

remark-gfm

GFM 表格、删除线、任务列表、自动链接

remark-math

行内 $...$ 和块级 $$...$$ 数学公式语法

rehype-raw

原始 HTML 透传(YouTube iframe、嵌入内容)

rehype-katex

将 LaTeX 数学公式渲染为 HTML

Mermaid 图表:

语言标记为 mermaid 的围栏代码块会被拦截,并由 MermaidBlock 组件渲染,该组件:

  1. 延迟加载 Mermaid 库

  2. 使用 Carbon 蓝色主题初始化(节点颜色 #d0e2ff、边框颜色 #0f62fe、连线颜色 #4589ff

  3. 通过 mermaid.render() 渲染 SVG

  4. 解析出错时回退到 <pre><code> 代码块

支持的图表类型:流程图、时序图、甘特图、实体关系图、状态机。

KaTeX 数学公式:

  • 行内公式:$T = \frac{N}{t}$ 以行内方式渲染

  • 块级公式:$$F^* = \arg\min_F [...]$$ 渲染为居中的块级方程式

  • KaTeX CSS 从 katex/dist/katex.min.css 导入

文章卡片设计

ArticleCard 组件使用分层点击目标模式:

  • 外层容器为 <div>``(而非 ``<a>),设置了 cursor: pointer

  • 标题 <Link>::after 伪元素覆盖整个卡片(position: absolute; inset: 0

  • 分类和标签的 <Link> 元素设置了 position: relative; z-index: 1,位于覆盖层之上,使其可独立点击

这种方式避免了无效的嵌套 <a> 标签,同时保持了整个卡片的可点击性。