Use Cases (更新: 2026/6/2)

用 Claude Code 构建博客 CMS:Astro MDX、多语言 SEO、质检与变现流程

用 Claude Code 和 Astro MDX 搭建博客 CMS,把内容结构、多语言、SEO、质检和 CTA 串成流程。

用 Claude Code 构建博客 CMS:Astro MDX、多语言 SEO、质检与变现流程

博客 CMS 不是写作工具,而是内容变现系统

很多技术博客的问题不是写得太少,而是发布流程太松。文章没有固定结构,翻译不同步,description 太长,代码没有验证,RSS 和 sitemap 没有更新,最后也没有把读者引导到产品、培训或咨询。

这里的 CMS 指 Content Management System,也就是内容管理系统:把文章按照固定格式保存、编辑、检查、预览和发布。它不一定一开始就是复杂后台。对 Astro 站点来说,Content Collections 加 MDX 已经可以形成一个轻量但严格的文件型 CMS。Claude Code 的价值,是把写作、翻译、代码检查、SEO 审核和 CTA 设计放进同一个编辑流程。

可以先阅读相关主题:Claude Code 与 Contentful CMS内容漏斗审计RSS 实现站点地图生成。官方资料建议直接看 Astro 的 Content CollectionsMDX integrationSitemap integration

先把 CMS 职责拆开

不要只对 Claude Code 说“做一个博客 CMS”。这个提示太宽,容易生成混合了数据库、后台、API、预览和发布逻辑的大块代码。文件型 CMS 更适合拆成可检查的责任。

模块作用适合交给 Claude Code 的任务
内容 schema规定 frontmatter 字段和类型编写 content.config.ts,修复类型错误
MDX 文章管理正文、表格、代码和 CTA改写草稿,补充示例
多语言同一个 slug 覆盖所有语言检查缺失语言,自然本地化
预览发布前确认页面显示启动 dev server,检查链接和排版
SEO管理标题、description、OGP、sitemap审核元数据和过长描述
QA gate在发布前挡住问题写校验脚本,运行构建
变现从文章导向产品、培训或咨询检查 CTA 和转化路径

三个真实用例

第一个用例是个人开发者的模板销售。写 Claude Code 教程时,可以在 CMS 中加入 ctaLabelctaUrl,让文章自然连接到付费模板、提示词库或小型课程。

第二个用例是公司技术博客。企业最怕发布看似正确但实际过时的内容,例如 API 名称已变、示例代码无法运行、只有日文更新而英文旧版仍在线。Claude Code 应该负责发布前检查,而不只是生成文章。

第三个用例是多语言 SEO。10 种语言要共用同一个 slug,比如 claude-code-blog-cms.mdx。标题可以本地化,但核心观点、代码示例、CTA 意图要保持一致,否则搜索流量和读者体验都会断裂。

site/src/content/blog/claude-code-blog-cms.mdx
site/src/content/blog-en/claude-code-blog-cms.mdx
site/src/content/blog-zh/claude-code-blog-cms.mdx
site/src/content/blog-ko/claude-code-blog-cms.mdx
site/src/content/blog-es/claude-code-blog-cms.mdx
site/src/content/blog-fr/claude-code-blog-cms.mdx
site/src/content/blog-de/claude-code-blog-cms.mdx
site/src/content/blog-pt/claude-code-blog-cms.mdx
site/src/content/blog-hi/claude-code-blog-cms.mdx
site/src/content/blog-id/claude-code-blog-cms.mdx

可复制的 Astro 内容 schema

schema 是“内容字段必须长什么样”的约定。下面的代码可以作为 src/content.config.ts 的起点使用。

// src/content.config.ts
import { defineCollection, z } from "astro:content";
import { glob } from "astro/loaders";

const blogSchema = z.object({
  title: z.string().min(20).max(80),
  description: z.string().min(40).max(120),
  pubDate: z.coerce.date(),
  updatedDate: z.coerce.date(),
  category: z.enum(["getting-started", "tips-and-tricks", "use-cases", "comparison", "advanced"]),
  tags: z.array(z.string()).min(2).max(8),
  heroImage: z.string().startsWith("/images/"),
  draft: z.boolean().default(false),
  requireAllLocales: z.boolean().default(false),
  lang: z.enum(["ja", "en", "zh", "ko", "es", "fr", "de", "pt", "hi", "id"]),
  ctaLabel: z.string().max(40).optional(),
  ctaUrl: z.string().url().optional(),
});

const makeBlogCollection = (base: string) =>
  defineCollection({
    loader: glob({ pattern: "**/*.{md,mdx}", base }),
    schema: blogSchema,
  });

export const collections = {
  blog: makeBlogCollection("./src/content/blog"),
  "blog-en": makeBlogCollection("./src/content/blog-en"),
  "blog-zh": makeBlogCollection("./src/content/blog-zh"),
  "blog-ko": makeBlogCollection("./src/content/blog-ko"),
  "blog-es": makeBlogCollection("./src/content/blog-es"),
  "blog-fr": makeBlogCollection("./src/content/blog-fr"),
  "blog-de": makeBlogCollection("./src/content/blog-de"),
  "blog-pt": makeBlogCollection("./src/content/blog-pt"),
  "blog-hi": makeBlogCollection("./src/content/blog-hi"),
  "blog-id": makeBlogCollection("./src/content/blog-id"),
};

MDX frontmatter 示例

MDX 可以理解为“能使用组件的 Markdown”。frontmatter 是文件顶部的元数据区,负责告诉列表页、RSS、OGP 和 sitemap 如何展示这篇文章。

---
title: "用 Claude Code 构建博客 CMS:Astro MDX、多语言 SEO、质检与变现流程"
description: "用 Claude Code 和 Astro MDX 搭建博客 CMS,把内容结构、多语言、SEO、质检和 CTA 串成流程。"
pubDate: "2025-12-22"
updatedDate: "2026-06-02"
category: "use-cases"
tags: ["Claude Code", "CMS", "博客运营", "Astro", "MDX"]
heroImage: "/images/hero/hero-036.png"
lang: "zh"
ctaLabel: "预约 Claude Code 内容运营咨询"
ctaUrl: "https://example.com/consulting"
---

## 第一节

本文把写作、翻译、SEO、质检和变现 CTA 放进同一个发布流程。

Node 发布前校验脚本

保存为 scripts/validate-blog-cms.mjs,在站点根目录运行 node scripts/validate-blog-cms.mjs claude-code-blog-cms

// scripts/validate-blog-cms.mjs
import fs from "node:fs";
import path from "node:path";

const slug = process.argv[2];
if (!slug) {
  console.error("Usage: node scripts/validate-blog-cms.mjs <slug>");
  process.exit(1);
}

const locales = [["blog", "ja"], ["blog-en", "en"], ["blog-zh", "zh"], ["blog-ko", "ko"], ["blog-es", "es"], ["blog-fr", "fr"], ["blog-de", "de"], ["blog-pt", "pt"], ["blog-hi", "hi"], ["blog-id", "id"]];
const root = path.join(process.cwd(), "src", "content");
const failures = [];

function readFrontmatter(source) {
  const match = source.match(/^---\n([\s\S]*?)\n---/);
  if (!match) return {};
  return Object.fromEntries(match[1].split("\n").flatMap((line) => {
    const index = line.indexOf(":");
    if (index === -1) return [];
    return [[line.slice(0, index).trim(), line.slice(index + 1).trim().replace(/^"|"$/g, "")]];
  }));
}

for (const [dir, lang] of locales) {
  const file = path.join(root, dir, `${slug}.mdx`);
  if (!fs.existsSync(file)) failures.push(`${dir}: missing file`);
  const source = fs.existsSync(file) ? fs.readFileSync(file, "utf8") : "";
  const data = readFrontmatter(source);
  if (data.lang !== lang) failures.push(`${dir}: wrong lang`);
  if (!data.updatedDate) failures.push(`${dir}: missing updatedDate`);
  if ((data.description || "").length > 120) failures.push(`${dir}: description too long`);
  if (!/https:\/\/docs\.astro\.build/.test(source)) failures.push(`${dir}: missing official docs`);
  if (!/\]\(\/blog\/claude-code-/.test(source)) failures.push(`${dir}: missing internal link`);
  if (!/(CTA|咨询|consult|training)/i.test(source)) failures.push(`${dir}: missing CTA`);
  if ((source.match(/`{3}/g) || []).length < 6) failures.push(`${dir}: fewer than three code blocks`);
}

if (failures.length) {
  console.error(failures.map((item) => `- ${item}`).join("\n"));
  process.exit(1);
}
console.log(`OK: ${slug} passed localized CMS checks.`);

给 Claude Code 的发布提示词

Rewrite the article for slug <slug> as a production-ready Astro MDX blog post.
- Edit only the localized files for this slug.
- Keep heroImage and category.
- Add updatedDate: "2026-06-02".
- Keep description within 120 characters.
- Include 3 real use cases, concrete pitfalls, runnable code, official Astro docs, internal links, and a monetization CTA.
- Report changed files and focused check results.

运营指标要提前写进 CMS

真正能变现的博客 CMS,不只保存标题和正文,还要让编辑在发布前看到“这篇文章为什么值得发”。建议在 frontmatter 或旁边的运营表里记录目标关键词、读者阶段、主要 CTA、关联商品、预计内部链接和复盘日期。这样 Claude Code 在改稿时不会只追求字数,而会围绕搜索意图和商业动作补内容。

例如一篇 Claude Code 入门文,读者可能还没有预算,只需要安全的第一步;这时 CTA 应该指向免费清单或训练营说明。另一篇 AWS Lambda 实战文,读者已经在排查部署问题,CTA 就可以指向咨询或模板包。CMS 把这些字段固定下来,团队就能比较不同文章的转化,而不是只看 PV。

发布后的复盘也要进入流程。每周检查 Search Console 的查询词、Cloudflare Web Analytics 的国家分布、训练页点击率和邮件咨询数。若文章有展示但点击率低,先改标题和 description;若点击进来马上离开,补导入文、图表和代码验证;若读完不咨询,说明 CTA 与读者阶段不匹配。Claude Code 可以负责生成修改建议,但最终判断要基于数据。

编辑审稿时要看的四个信号

第一,看文章是否有自己的经验。只是复述官方文档,很容易被判断为低价值内容。第二,看代码是否能在本地复制执行,至少要说明依赖、目录和运行命令。第三,看多语言版本是否本地化,而不是把日语例子直译到所有市场。第四,看内部链接是否真的帮助读者继续学习,而不是为了 SEO 生硬堆链接。

如果这些信号都通过,再让 Claude Code 做标题候选、FAQ、比较表和结构化摘要,效果会更稳定。反过来,如果原稿没有读者问题、没有实际验证、没有下一步行动,AI 再润色也只是把薄内容写得更流畅,不能真正提高转化。

常见失败模式

第一,只有主语言更新,其他语言停留在旧代码。第二,Claude Code 的写入范围太大,误改其他 slug。第三,代码块是伪代码,读者复制后无法运行。第四,CTA 太硬,只像广告,不像下一步帮助。第五,更新日期只是机械修改,没有重新确认官方文档和实际代码。

实际验证中,schema 可以挡住缺失日期,Node 脚本可以发现过长 description、缺少官方链接、缺少内部链接和 CTA。机器检查无法判断中文是否自然,也无法判断咨询导线是否有说服力,所以发布前仍需要人工读一遍。对于想把技术博客变成培训、模板销售或顾问业务入口的团队,先搭好这个 CMS 和 QA gate,比单纯增加文章数量更有效。

#Claude Code #CMS #博客运营 #Astro #MDX
免费

免费 PDF: Claude Code 速查表

输入邮箱即可获取一页 PDF,整理常用命令、审查习惯和安全工作流。

我们会妥善保护你的信息,不发送垃圾邮件。

把 Claude Code 变成真正能带来结果的工作流

先领取中文说明的免费 PDF,再进入英文商品页选择合适的教材。如果你需要团队落地、流程设计或内容变现支持,也可以直接咨询。

Masa

关于作者

Masa

专注 Claude Code 实务流程、团队导入和内容转化的工程师。