你的网站每次更新,是不是都在“盲推”?

刚上线的页面,title 写成“Untitled”,图片全没 alt,某个重要栏目链接点开直接 404——这些不是上线后才该发现的事。它们本该在代码合并前就被揪出来。

问题不在人,而在流程:SEO检查还没被真正“塞进”你的 CI/CD 里。

为什么CI/CD必须集成SEO检查?

SEO 往往被当成上线后的“补救动作”:内容写完→开发部署→SEO 团队翻日志、跑爬虫、发整改单。等反馈回来,版本都发第二版了。

CI/CD 的本质是“早发现、快修复”。把 SEO 检查变成自动化测试,就像跑 ESLint 或单元测试一样自然——每次提交、每次 PR,它就默默跑一遍。错的不是人,是流程没给它位置。

一个做母婴电商的团队试了这个做法:他们在商品卡片组件的构建脚本里加了一条规则——如果生成的 HTML 里没有 <title><h1>,构建直接失败。结果?再没出现过整批商品页被搜索引擎判为“空内容”的事故。

集成哪些SEO检查项最有效?

先别想着全覆盖。盯住那些一出错就让页面“隐身”的硬伤,从最稳、最易落地的开始。

第一,关键标签不能丢。
自动检查每个页面是否包含 <title><meta name="description"><h1>,且内容不为空、长度不过长(比如 <title> 超过 60 字符就标黄提醒)。

第二,链接别断、路径别乱。
扫描新提交的模板或路由配置,确认没有硬编码的 404 链接;检查站内 href 是否指向真实存在的路径,尤其注意带重写规则的 URL(比如 /article/123/post/123)是否仍能解析。

第三,基础可访问性要过关。
图片有没有 alt?纯图标按钮有没有 aria-label?这些不是“加分项”,而是 Google 抓取和用户阅读的共同门槛。

第四,SPA 页面得让搜索引擎看得见。
如果你用 Vue 或 React 做 SSR 或静态生成,就在构建后用无头浏览器打开几个核心页面,确认关键文案(比如文章标题、产品名称)真实出现在 DOM 里,而不是只藏在 JS 中。

如何选择适合你的SEO检查工具?

别被工具名吓住。你不用换掉整个流水线,只要挑能插进现有环节的那一小块。

轻量起步,用 Lighthouse CI。
它跑在 Node.js 上,GitHub Actions、GitLab CI、Jenkins 全支持。你只需配一行命令,让它只跑 SEO 和可访问性审计,分数不达标就让 CI 失败。连报告都能自动生成 HTML,直接发 Slack。

需要更细粒度控制?写个脚本就行。
比如用 cheerio 解析构建输出的 HTML 文件,几行代码就能断言:“首页必须有 <title>,且文本长度在 30–60 字之间”。不需要新账号,不依赖外部服务,就是你项目里的一个 .js 文件。

想看真实渲染效果?Playwright 是现成的选择。
很多前端团队已经在用它写 E2E 测试。复用同一套环境,打开预发布地址,检查关键元素是否渲染成功、是否含关键词——不用额外装工具,也不用学新语法。

有个做知识付费的团队就这么干:他们把 Playwright 脚本加在 Staging 部署后,只测 5 个核心页面(首页、课程列表、详情页、老师页、关于我们),10 秒内跑完,结果直接贴在 PR 评论区。

在CI/CD流水线的哪个环节加入检查?

检查不是越靠前越好,也不是越多越好。关键是让它在“人还来得及改”的时候说话。

第一个位置:提交前(pre-commit)。
只跑最快、最确定的检查,比如 Front Matter 里 title 字段是否存在、YAML 格式是否合法。防止低级错误进仓库。

第二个位置:PR / MR 评审时(最关键的卡点)。
CI 自动运行完整 SEO 检查套件,并把结果(通过/失败 + 具体哪一页哪条规则不满足)直接贴在 PR 评论里。开发和 SEO 同时看到——不是“你错了”,而是“我们发现了这个可改点”。

第三个位置:Staging 部署后。
用真实 URL 跑一次最终校验。这时候能暴露 CDN 缓存、服务器重定向、.htaccess 规则等环境相关的问题。不是为了卡发布,而是为了提前踩坑。

如何让开发和SEO团队真正协作起来?

技术能搭桥,但人得愿意过桥。

把 SEO 检查项写成白纸黑字的“交付红线”:比如“所有新页面模板必须提供 titledescription 的占位逻辑”,就像“所有 API 接口必须返回标准错误格式”一样,是团队共同认可的质量底线。

让结果看得见。把 CI 中 SEO 检查的通过率、高频失败项做成一张简单图表,挂在团队每天刷的钉钉群或飞书多维表格里。谁都能看见上周漏掉了 3 次 alt,而这次 PR 已经自动拦住了。

每周花 15 分钟一起看一眼:哪些问题被 CI 拦下了?哪些又绕过了检查跑到线上?根据真实反馈调规则——比如发现 description 经常超长,就把它从“警告”升级为“失败”。

今天下班前就能执行的一个具体步骤

现在就打开你项目的 Git 仓库,做这一件事:给文章页模板加一个“有没有 <title>”的检查。

  1. 在项目根目录新建文件 scripts/seo-title-check.js
  2. 粘贴这段代码(用你已有的 jsdomcheerio):
    const fs = require('fs');
    const { JSDOM } = require('jsdom');
    const html = fs.readFileSync('./dist/article/index.html', 'utf8');
    const dom = new JSDOM(html);
    const title = dom.window.document.querySelector('title');
    if (!title || !title.textContent.trim()) {
      console.error('❌ 文章页缺失 <title> 标签或内容为空');
      process.exit(1);
    }
    console.log('✅ 文章页 <title> 检查通过');
    
  3. package.jsonscripts 里加一句:"check:title": "node scripts/seo-title-check.js"
  4. 运行 npm run check:title,看看它能不能报错/通过
  5. 打开你的 .github/workflows/ci.yml(或 .gitlab-ci.yml),在 testbuild 步骤后加一行:
    - run: npm run check:title
    

它只有 10 行,但它会第一次在 PR 里告诉你:“这篇文章页,没 title”。从这一行开始,SEO 就不再是上线后的事了。