content

博客 CMS

TanStack Ship 博客 CMS,支持多语言技术博客、MDX 内容、Shiki 代码高亮、Mermaid 图表和 SEO 优化。

博客文章创建和编辑,支持丰富的 MDX 内容(含代码块和图表)
多语言博客文章,支持兄弟链接和语言切换
标签系统用于内容分类,支持彩色编码分类法
作者管理,含详细资料、简介和社交链接
内容分页和基于共享标签的相关文章推荐
SEO 元数据,含多语言 SEO 优化的 hreflang 标签
阅读时间估算和自动生成的目录
Open Graph 元标签和规范 URL 支持
其他语言:English·Deutsch

概述

TanStack Ship 的博客 CMS 提供了一套完整的、生产就绪的内容管理系统,专为规模化技术博客而设计。基于 MDX 构建,集成 Shiki 驱动的语法高亮和 Mermaid 图表渲染,支持涵盖代码教程、架构文档和多语言发布工作流的丰富技术内容创作。

作为 TanStack Ship 平台的一部分,博客 CMS 与 R2 无服务器存储(媒体资产管理)、XML 站点地图系统(SEO 可见性)以及完整的内容管理工作流管理界面深度集成。文章存储在数据库中,支持完整的 CRUD 操作,而公共博客则具备分页、相关文章推荐和面向全球受众的无缝多语言切换功能。


设计流程

博客 CMS 编排从作者创作到 MDX 编译再到多语言交付的完整内容发布管道:


核心能力

丰富的 MDX 内容创作

博客文章采用 MDX 格式编写,结合标准 Markdown 和内嵌 React 组件,实现丰富的交互式内容:

  • 富 Markdown — 完整 Markdown 支持,包括标题、表格、列表、链接、图片和块引用
  • 代码块 — 通过 Shiki 集成实现语法高亮,支持 100+ 种编程语言,附带一键复制功能
  • Mermaid 图表 — 使用 Mermaid DSL 在博客内容中直接渲染流程图、时序图、甘特图和类图
  • 前置元数据 — 结构化元数据包括标题、描述、标签、作者归属、发布日期和语言信息
  • 自定义组件 — 嵌入 React 组件实现交互演示、计算器和数据可视化

多语言发布

每篇博客文章可通过兄弟文章关系系统支持多种语言:

  • 兄弟链接 — 不同语言的文章通过 siblingPosts 数据库关系关联,实现跨语言的内容同步
  • hreflang SEO 标签 — 自动生成的 hreflang 元标签向搜索引擎指示语言和地区定位,实现多语言 SEO
  • 语言切换器 — 详情页上的语言感知导航组件,让读者可在可用语言版本间切换
  • 共享 Slug — 所有语言版本共享一个英文 slug,通过语言前缀区分 URL(例如英文 /blog/slug,中文 /zh/blog/slug)

内容组织和发现

系统提供强大的内容分类和发现机制:

  • 标签系统 — 文章可添加彩色编码的分类标签。标签包含名称、描述性 slug 和用于 UI 展示的视觉颜色标识符
  • 标签聚合页 — 专用标签索引页面,聚合所有共享特定标签的文章,支持分页
  • 相关文章推荐 — 系统基于共享标签重叠度推荐文章,提高内容参与度并降低跳出率
  • 分页 — 博客列表主页面支持可配置的分页,适用于大量内容

作者管理

每篇博客文章归属于一位作者,配套完整的资料系统:

  • 作者简介 — 个人信息包括姓名、简介、头像和社交链接
  • 作者详情页 — 自动聚合指定作者的所有文章,展示在专用列表页上
  • 协作发布 — 多位作者可为同一博客贡献内容,支持每篇文章独立署名

客户端博客文章列表示例:

tsx
import { useQuery } from '@tanstack/react-query'

export function BlogList() {
  const { data } = useQuery({
    queryKey: ['blog-posts'],
    queryFn: () =>
      fetch('/api/blog/posts?page=1&limit=5').then((r) => r.json()) as Promise<
        Array<{
          slug: string
          title: string
          description: string
          tags: Array<{ name: string }>
          readingTime: number
          author: { name: string }
        }>
      >,
  })

  return (
    <div className="space-y-4">
      {data?.map((post) => (
        <article key={post.slug} className="rounded-lg border p-4">
          <h3 className="font-semibold">{post.title}</h3>
          <p className="mt-1 text-sm text-muted-foreground">{post.description}</p>
          <div className="mt-2 flex items-center gap-2 text-xs text-muted-foreground">
            <span>{post.author.name}</span>
            <span>·</span>
            <span>{post.readingTime} 分钟阅读</span>
            <span>·</span>
            {post.tags.map((t) => (
              <span key={t.name} className="rounded-md bg-muted px-2 py-0.5">{t.name}</span>
            ))}
          </div>
        </article>
      ))}
    </div>
  )
}

设计理念

技术内容优先

博客 CMS 专为包含代码、图表和交互元素的技术内容而构建。与将代码块视为二等格式的通用 CMS 平台不同,带有 Shiki 语法高亮的 MDX 内容和 Mermaid 图表渲染是一等公民。这种技术内容优先的方法确保开发者可以使用他们期望的工具——语法高亮的代码示例、架构流程图、时序图——无需变通或妥协。与 WordPress 或 Contentful 不同——它们需要插件来实现代码高亮和基于嵌入的图表工具——我们的博客 CMS 将 Shiki 语法高亮和 Mermaid 图表渲染直接内建到内容管道中,无需任何第三方服务或 iframe 嵌入。

多语言 SEO 内建设计

多语言发布不是事后考虑——它通过兄弟文章关系、共享 slug 和语言前缀 URL 内建到内容模型中。每篇文章自动生成 hreflang 元标签,告诉搜索引擎文章的语言变体,在最大化多语言搜索可见性的同时防止重复内容惩罚。语言特定的 URL 结构(/en/blog/slug、/zh/blog/slug、/de/blog/slug)为用户和搜索爬虫提供了清晰的语言信号。

通过缓存提升性能

MDX 编译——包括 Shiki 语法高亮和 Mermaid 图表渲染——计算密集。系统不是在每次请求时重新编译,而是缓存编译后的输出,仅在文章更新时使缓存失效。这种缓存优先的方法意味着博客文章对读者来说即刻加载,即使包含复杂的代码块或图表,而内容作者通过缓存失效触发器仍能立即看到他们的编辑生效。


最佳实践

SEO 优化内容结构

使用清晰的标题层级组织博客文章:单个 H1 用于标题(从前置元数据自动生成)、描述性 H2 用于主要章节、H3 用于子章节。这种层级结构既提升读者理解度,也有助于搜索引擎抓取。始终在前置元数据中包含引人注目的元描述,以在搜索结果中获得丰富摘要展示。

多语言内容策略

发布多语言内容时,独立撰写每个语言版本,而不是使用机器翻译。每个版本应针对目标受众进行文化适配。使用兄弟链接系统关联版本——避免在没有语言正当性的情况下跨语言复制内容,这可能触发重复内容惩罚。

图片和媒体管理

将博客图片上传到 R2 存储,通过公开 URL 引用。上传前优化图片——压缩 PNG、尽可能使用 WebP 格式、为无障碍和 SEO 添加描述性替代文本。对于图表,优先使用 Mermaid 原生渲染而非静态图片,以确保跨设备和屏幕分辨率的清晰显示。

内容缓存策略

利用服务端缓存机制缓存编译后的 MDX 内容。编译步骤(Shiki 高亮、Mermaid 渲染)计算密集——缓存的文章可瞬间提供。配置缓存失效以在文章更新时触发,确保读者始终看到最新版本。


常见问题

如何创建新的博客文章? 导航到 /dashboard/admin/blog 并点击"新文章"。填写标题、内容(MDX)、描述、标签和作者信息。设置语言和发布状态,然后保存。对于多语言文章,创建兄弟版本并通过兄弟文章选择器关联。

能否在博客文章中使用自定义 React 组件? 可以。MDX 允许在博客内容中直接嵌入 React 组件。在 MDX 提供者配置中注册的组件均可使用。常见用例包括交互式代码沙箱、数据表格和标注框。

标签系统如何用于内容发现? 每篇文章可以拥有多个标签。标签从管理面板管理,支持用于视觉区分的颜色编码。博客列表页面包含标签筛选器,专用标签页面聚合所有共享特定标签的文章。

阅读时间估算是如何工作的? 阅读时间基于 MDX 内容的字数计算,英文内容使用每分钟 200-250 词的平均阅读速度,中文和其他表意文字语言使用调整后的速率。

作者在发布后能否编辑自己的文章? 可以。具有适当权限的作者可以通过管理界面编辑已发布的文章。编辑后的文章保留原始 slug 和发布日期,updatedAt 时间戳反映修订版本。

博客文章如何包含在 XML 站点地图中? 博客文章通过站点地图集成模块自动包含在 XML 站点地图中。每篇文章获得一个独立条目,包含语言对应 URL,多语言文章包含 hreflang 替代链接,实现全面的多语言 SEO 覆盖。

博客内容有哪些分析指标? 博客文章浏览量通过分析系统追踪。管理仪表板提供每篇文章的浏览次数、阅读时间指标和参与度数据。UTM 参数可附加到博客文章 URL 上,用于活动归因追踪。


配置

博客内容通过管理界面管理。主要管理路由包括:

  • /dashboard/admin/blog — 文章列表、创建、编辑和删除
  • /dashboard/admin/blog/tags — 标签创建、编辑、颜色分配和删除
  • /dashboard/admin/blog/authors — 作者资料管理(姓名、简介、头像、社交链接)

基本博客功能无需额外环境变量。对于图片上传,请按照 R2 文件管理文档配置 R2 存储。博客 Schema 的数据库迁移包含在标准迁移集中,通过 npm run db:migrate 应用。


集成点

博客 CMS 与以下 TanStack Ship 平台模块集成:

  • R2 上传 — 博客文章图片、封面照片和媒体资产存储在 R2 对象存储中并提供服务
  • 站点地图系统 — 博客文章包含在 XML 站点地图中,支持 hreflang 注释和分页
  • SEO 框架 — 完整的 Open Graph 元标签、规范 URL 和 hreflang 支持,用于搜索引擎优化
  • 站内搜索 — 博客内容被索引,可通过全站搜索功能访问
  • 分析系统 — 文章浏览追踪和参与度指标被输入分析仪表板
  • 邮件营销 — 新博客文章通知可通过邮件活动系统触发,用于订阅者互动