Use Cases (업데이트: 2026. 6. 2.)

Claude Code로 블로그 CMS 만들기: Astro MDX, 다국어 SEO, QA와 수익화 흐름

Claude Code와 Astro MDX로 스키마, 번역, SEO, QA, CTA까지 연결되는 블로그 CMS를 구축합니다.

Claude Code로 블로그 CMS 만들기: Astro MDX, 다국어 SEO, QA와 수익화 흐름

블로그 CMS는 글쓰기 도구가 아니라 운영 시스템이다

기술 블로그가 자주 올라와도 교육 문의, 템플릿 판매, 컨설팅으로 이어지지 않는 경우가 많습니다. 원인은 글의 양보다 게시 전 운영에 있습니다. 메타데이터가 흔들리고, 번역이 동기화되지 않고, 코드가 실행되지 않으며, 마지막 CTA가 독자의 다음 행동과 맞지 않으면 좋은 글도 성과를 내기 어렵습니다.

CMS는 Content Management System, 즉 콘텐츠를 정해진 형식으로 저장하고 편집하고 검수하고 배포하는 시스템입니다. Astro의 Content Collections와 MDX를 쓰면 파일 기반으로도 충분히 엄격한 CMS를 만들 수 있습니다. Claude Code는 여기서 초안 작성자뿐 아니라 편집 운영자, 번역 검수자, QA 도구 작성자로 쓰는 것이 좋습니다.

관련 글로 Claude Code와 Contentful CMS, 콘텐츠 퍼널 감사, RSS 구현, 사이트맵 생성을 함께 보면 흐름이 분명해집니다. 공식 문서는 Astro Content Collections, MDX integration, Sitemap integration을 기준으로 삼으세요.

역할을 나누면 Claude Code가 더 정확해진다

“블로그 CMS를 만들어줘”라는 요청은 너무 넓습니다. 스키마, 에디터, API, 미리보기, 배포가 한꺼번에 섞일 수 있습니다. 파일 기반 Astro CMS에서는 책임을 작게 나누는 편이 안전합니다.

영역역할Claude Code에 맡길 일
content schemafrontmatter 필드와 타입 정의content.config.ts 작성, 타입 오류 수정
MDX article본문, 표, 코드, CTA 관리초안 개선, 예제 보강
localization같은 slug를 여러 언어에 유지누락 파일 탐지, 자연스러운 번역
preview게시 전 화면 확인개발 서버 실행, 링크와 레이아웃 점검
SEOtitle, description, OGP, sitemap 관리메타데이터 감사
QA gate문제 있는 글을 게시 전에 차단Node 검사 스크립트 작성
monetization상품, 교육, 상담으로 연결CTA 위치와 문구 검토

실제 사용 사례 3가지

첫째, 개인 개발자는 Claude Code 튜토리얼을 유료 템플릿이나 프롬프트 라이브러리로 연결할 수 있습니다. 이때 CMS에는 ctaLabel, ctaUrl, relatedPosts, updatedDate, heroImage가 필요합니다.

둘째, 회사 기술 블로그는 잘못된 정보를 막아야 합니다. 오래된 API 이름, 실행되지 않는 코드, 일부 언어만 업데이트된 번역, 깨진 OGP 이미지는 신뢰를 떨어뜨립니다. Claude Code에는 작성보다 공개 전 검사를 맡기는 것이 효과적입니다.

셋째, 다국어 SEO에서는 같은 slug가 계약입니다. 제목은 현지 독자에게 맞게 바꾸되, 핵심 주장과 코드 예제, 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 content schema

schema는 콘텐츠의 약속입니다. title은 문자열, description은 120자 이하, lang은 정해진 언어 코드여야 한다는 식으로 빌드 전에 확인합니다.

// 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, CTA에 필요한 정보를 담는 머리말입니다.

---
title: "Claude Code로 블로그 CMS 만들기: Astro MDX, 다국어 SEO, QA와 수익화 흐름"
description: "Claude Code와 Astro MDX로 스키마, 번역, SEO, QA, CTA까지 연결되는 블로그 CMS를 구축합니다."
pubDate: "2025-12-22"
updatedDate: "2026-06-02"
category: "use-cases"
tags: ["Claude Code", "CMS", "블로그 운영", "Astro", "MDX"]
heroImage: "/images/hero/hero-036.png"
lang: "ko"
ctaLabel: "Claude Code 콘텐츠 운영 상담 예약"
ctaUrl: "https://example.com/consulting"
---

## 첫 섹션

이 글은 작성, 번역, SEO, QA, 수익화 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`);
  const source = fs.existsSync(file) ? fs.readFileSync(file, "utf8") : "";
  const data = readFrontmatter(source);
  if (!source) failures.push(`${dir}: missing file`);
  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.

실패 사례와 확인 결과

대표적인 실패는 한 언어만 갱신하는 것, Claude Code에 너무 넓은 쓰기 범위를 주는 것, 실행되지 않는 코드 블록을 올리는 것, CTA를 광고 문구처럼만 쓰는 것입니다. RSS, sitemap, OGP도 게시 흐름에 포함해야 합니다. 글 파일이 있어도 피드에 없고 검색엔진에 전달되지 않으면 독자에게 도달하지 않습니다.

직접 검증했을 때 schema는 날짜 누락을 잡았고, Node 스크립트는 긴 description, 공식 링크 누락, 내부 링크 누락, CTA 누락을 발견했습니다. 다만 한국어 번역의 자연스러움과 교육/컨설팅 CTA의 설득력은 자동화로 충분히 판단할 수 없어, 마지막에는 사람이 읽고 확인해야 합니다.

#Claude Code #CMS #블로그 운영 #Astro #MDX
무료

무료 PDF: Claude Code 치트시트

이메일을 입력하면 명령, 리뷰 습관, 안전한 워크플로를 정리한 PDF를 받을 수 있습니다.

개인정보를 안전하게 관리하며 스팸을 보내지 않습니다.

Masa

작성자 소개

Masa

Claude Code 실무 워크플로와 팀 도입을 검증하는 엔지니어입니다.