← 全部文章

一次博客 SSG 静态化改造实录

记录一次从纯 SPA 到 SSG + SPA 水合的演进过程

更新于 2026.08.07

本文目录 9 节
一次博客 SSG 静态化改造实录封面

前言,阅读本文前,请熟悉以下英文缩写。 SPA:Single Page Application,单页面应用 CSR:Client-Side Rendering,客户端渲染 SSR:Server-Side Rendering,服务端渲染 SSG:Static Site Generate,静态站点生成

背景:为什么要折腾 SSG?

我的博客最初是一个典型的SPA架构:

  • 前端:Vue 3 + Vite + TypeScript
  • 后端:Spring Boot
  • 文章内容:Markdown 存在数据库中
  • 渲染方式:纯 CSR(客户端渲染)

这个架构对「人」非常友好,但对「搜索引擎」和「爬虫」并不友好。

问题

访问文章页时,页面源代码里只有:

<div id="app"></div>

文章内容完全依赖 JS 渲染。 结果就是:

  • 搜索引擎抓不到正文
  • AI 搜索 / AI 摘要工具“看不到内容”
  • 搜索引擎站长工具给出负面评价
  • 在QQ、微信等平台发送链接解析不出文章标题

于是,一个目标非常明确的需求出现了:

在不重构整个前端的前提下,让文章页对爬虫是“完整 HTML”。

方案选择

在动手之前,我给自己设定了几条硬约束。

  • 不引入 Nuxt / SSR(成本太高)
  • 不重写现有 Vue 页面
  • 只改造文章详情页
  • 普通用户体验不能明显变差

方案调研

在调研了几种方案后,大致有这些选择:

方案问题
SSR(Nuxt)架构侵入性太强
构建期预渲染动态文章不适合
Headless Chrome资源消耗大

我并不想把太多精力放在前端上,Nuxt和Headless Chrome的改造是绝对不考虑的。并且由于我这是动态站,并不是JavaGuide这种文档站,所以也不太适合用VuePress、VitePress这种工具。

方案实现过程

我的博客文章本质上是:数据库中的Markdown+ HTML模板,前端用Node.js脚本从后端取出文章信息提前渲染好HTML,在访问时根据UA判断是爬虫还是访客,爬虫则展示SSG、访客则展示SPA。这样保证文章内容可被抓取同时访客还有良好的交互体验。

弯路一:通过UA判断爬虫

本想通过UserAgent判断百度蜘蛛和BingBot等爬虫,但测试后发现效果不佳。因为OpenAI以及其他一众AI爬虫并无固定的UA,无法识别这些爬虫。在AI时代的当下,应当对这些AI访问网页的爬虫工具提供良好支持。

弯路二:统一返回SSG、评论区CSR加载

这一步通过预设HTML模板,返回与SPA长得差不多的SSG,评论等用CSR实现。逻辑上是差不多的。 为了适配 SSG 页面,前端不得不开始处理:

  • 判断当前是否运行在 SSG 页面中
  • 区分「静态首屏」和「完整 SPA」
  • 某些逻辑只能在 CSR 阶段执行

虽然这些都能解决,但我很快意识到:前端复杂度在被动上升。

最终:SSG 首屏 + SPA 自动切换(水合)」

核心思路:

  • 所有请求先返回 SSG 静态页面(爬虫友好)
  • SSG 页面内嵌 JavaScript,检测到普通浏览器后自动跳转到 SPA
  • 爬虫不执行 JS,直接抓取静态内容

这样一来,实现反而简单了,用户体验也更好了。 SSG 模板内嵌脚本:

<script>
  (function() {
    // 已经带有 spa=1 参数说明是跳转后的请求,不再处理
    if (window.location.search.includes('spa=1')) return;

    // 跳转到 SPA 版本
    var articleId = {{articleId}};
    window.location.replace('/article/' + articleId + '?spa=1');
  })();
</script>

Vue Router 清理参数:

router.beforeEach((to, _from, next) => {
  // 清理 SSG 水合跳转时添加的 spa=1 参数
  if (to.query.spa === '1') {
    const { spa, ...restQuery } = to.query;
    next({ ...to, query: restQuery, replace: true });
    return;
  }
  next();
});

这个方案带来了很多优势: 功能方面,

特性SSG 首屏 + SPA 水合
SEO爬虫获取完整静态内容
首屏速度静态 HTML 秒开
用户体验自动切换到完整 SPA
维护成本无需维护 UA 列表
可靠性100% 可靠,无边界情况

安全方面,

层级保护机制
SSG 层只有 status = "published" 的文章才生成静态 HTML
Nginx 层静态文件不存在时回退到 SPA
后端 API 层未发布文章需要登录才能访问

成果

到此,本站的SSG改造已经完成。将文章链接喂给AI等可正常解析内容。

评论