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

Claude Code와 Sanity CMS: 2026 콘텐츠 운영 실전 가이드

Sanity CMS와 Claude Code로 SEO 콘텐츠, 상품 페이지, 다국어 운영, 수익화 CTA를 설계합니다.

Claude Code와 Sanity CMS: 2026 콘텐츠 운영 실전 가이드

Sanity CMS란 무엇인가

Sanity CMS는 글, 랜딩 페이지, 상품 제안, FAQ, 작성자 정보, 캠페인 문구, CTA를 구조화해서 관리하는 headless CMS입니다. headless CMS는 편집 화면과 실제 웹사이트를 분리한 CMS라는 뜻입니다. 편집자는 Sanity Studio에서 콘텐츠를 만들고, 웹사이트나 앱은 API로 필요한 데이터만 가져옵니다. 그래서 같은 콘텐츠를 블로그, 문서 사이트, 뉴스레터, 세일즈 페이지, 내부 도구에서 함께 사용할 수 있습니다.

콘텐츠 운영과 수익화를 생각하면 CMS는 단순한 글 저장소가 아닙니다. 좋은 CMS는 검색 의도, 타깃 키워드, 내부 링크, 상품 CTA, 검증 메모, 업데이트 날짜, 리뷰 담당자를 데이터로 관리합니다. 이 구조가 있어야 Claude Code가 schema, GROQ query, fetch 함수, 타입, 품질 검사 스크립트를 안정적으로 만들어 줄 수 있습니다.

Sanity의 필드 타입은 공식 Sanity Schema Types에서 확인할 수 있고, 데이터 조회 언어는 공식 GROQ syntax를 보면 됩니다. Claude Code는 이 문서를 바탕으로 초안을 빠르게 만들 수 있지만, 운영 규칙은 사람이 정해야 합니다. slug 중복, draft 노출, 이미지 alt, CTA 누락, 분석 이벤트 이름은 실제 매출과 신뢰에 연결되기 때문입니다.

2026년에 Sanity를 도입한다면 첫 질문은 “어떤 편집기가 편한가”가 아니라 “어떤 콘텐츠 단위가 매출에 영향을 주는가”입니다. 블로그 글에는 검색 의도와 CTA가 있어야 하고, 상품 페이지에는 대상 독자와 비교 기준이 있어야 하며, 교육 또는 상담 페이지에는 문의 전에 확인해야 할 정보가 있어야 합니다. Sanity는 이 항목을 구조화하고, Claude Code는 그 구조를 코드로 유지하게 해 줍니다.

2026 프로덕션 아키텍처

수익화가 있는 콘텐츠 사이트에서는 Sanity Studio, Content Lake, 프런트엔드, 분석, 판매 흐름을 분리해서 설계해야 합니다. 아래 표는 작은 미디어, 템플릿 판매 사이트, B2B 콘텐츠 마케팅 팀이 바로 적용하기 쉬운 기준입니다.

계층프로덕션 역할확인할 지표Claude Code가 도울 작업
Sanity Studio글, 상품, FAQ, CTA, 리뷰 메모 편집필수값 누락, 대기 중인 리뷰, 오래된 draftschemaTypes, preview, validation
Content Lake구조화된 콘텐츠를 API로 제공query 크기, 캐시, dataset 분리GROQ, draft 제외, locale 필터
FrontendSEO 페이지, 목록, 상세, 랜딩 페이지 표시색인 수, 속도, CTA 클릭fetch helper, 타입, 컴포넌트
Analytics/CRM방문, 구매, 문의를 연결이벤트, 폼 시작률, 구매율, 상담 전환이벤트 명세, QA checklist
Monetization무료 PDF, 유료 템플릿, 교육, 상담매출, 환불 이유, 리드 품질CTA 변형, 비교표, FAQ, offer routing

이 구조의 핵심은 본문에 모든 것을 넣지 않는 것입니다. CTA는 별도 객체로 관리해야 테스트할 수 있습니다. FAQ는 여러 페이지에서 재사용해야 합니다. 작성자 정보는 작성자 문서에서 가져와야 합니다. 리뷰 상태는 메신저 대화가 아니라 필드여야 합니다. 그래야 콘텐츠 운영이 자동 점검과 개선 대상이 됩니다.

관련 내용은 Claude Code blog CMS, CMS 비교 관점은 Claude Code Contentful CMS, CMS 데이터를 앱이나 API로 연결하는 방법은 Claude Code API development와 함께 보면 좋습니다. 팀 도입, 교육, 운영 설계는 training / consultation으로 이어질 수 있습니다.

실제로 효과가 있는 사용 사례

첫 번째 use case는 다국어 SEO 콘텐츠 운영입니다. 하나의 원문을 영어, 일본어, 중국어, 한국어, 스페인어 등으로 확장할 때 본문만 번역하면 품질이 빨리 무너집니다. Sanity에 locale, canonicalSlug, targetKeyword, searchIntent, localizedCta를 저장하면 언어별 검색 의도와 CTA를 따로 조정할 수 있습니다. Claude Code는 누락된 내부 링크, 긴 description, 없는 CTA, 오래된 공식 링크를 검사하는 스크립트를 만들 수 있습니다.

두 번째 use case는 콘텐츠에서 상품으로 이어지는 funnel입니다. 초보자는 무료 PDF가 필요할 수 있고, 구현자는 템플릿을 원할 수 있으며, 팀 리드는 도입 상담이 필요할 수 있습니다. 모든 글 끝에 같은 버튼을 붙이면 전환율이 낮습니다. Sanity에 cta.intent, cta.label, cta.href를 구조화하면 글의 의도에 따라 무료 자료, 유료 가이드, 구현 리뷰, 교육 상담을 다르게 노출할 수 있습니다.

세 번째 use case는 CMS 마이그레이션과 콘텐츠 감사입니다. WordPress, Contentful, Notion, Markdown에서 Sanity로 옮길 때 단순 이전만 하면 오래된 문제도 같이 옮겨집니다. 마이그레이션 시점에 유입은 있지만 CTA가 없는 글, 상품 링크는 있지만 증거가 약한 글, 중복 주제, 오래된 외부 링크를 분류해야 합니다. contentScore, lastReviewedAt, reviewOwner, monetizationStatus 같은 필드를 두면 운영 backlog가 보입니다.

네 번째 use case는 공개 콘텐츠와 세일즈 자료의 공통화입니다. B2B 팀에서는 웹사이트 설명, 영업 자료, FAQ, 지원 답변이 서로 달라지기 쉽습니다. Sanity에 기능 설명, 반론 처리, proof point, FAQ를 문서로 저장하면 공개 페이지와 내부 도구가 같은 원본을 사용할 수 있습니다. Claude Code는 이를 가져오는 API, 컴포넌트, 내부 dashboard를 만들 수 있습니다.

복사해서 시작하는 schema

아래 코드는 Sanity v3 프로젝트에서 schemaTypes/post.ts로 사용할 수 있는 최소 schema입니다. 제목, slug, locale, SEO description, alt가 필수인 hero image, 본문, 수익화 CTA, 검증 메모, 발행일을 포함합니다.

// schemaTypes/post.ts
import {defineField, defineType} from 'sanity'

export const post = defineType({
  name: 'post',
  title: 'Post',
  type: 'document',
  fields: [
    defineField({
      name: 'title',
      title: 'Title',
      type: 'string',
      validation: (rule) => rule.required().max(90),
    }),
    defineField({
      name: 'slug',
      title: 'Slug',
      type: 'slug',
      options: {source: 'title', maxLength: 96},
      validation: (rule) => rule.required(),
    }),
    defineField({
      name: 'locale',
      title: 'Locale',
      type: 'string',
      options: {
        list: [
          {title: 'English', value: 'en'},
          {title: 'Japanese', value: 'ja'},
          {title: 'Korean', value: 'ko'},
        ],
      },
      validation: (rule) => rule.required(),
    }),
    defineField({
      name: 'description',
      title: 'SEO description',
      type: 'text',
      rows: 3,
      validation: (rule) => rule.required().max(120),
    }),
    defineField({
      name: 'heroImage',
      title: 'Hero image',
      type: 'image',
      options: {hotspot: true},
      fields: [
        defineField({
          name: 'alt',
          title: 'Alt text',
          type: 'string',
          validation: (rule) => rule.required(),
        }),
      ],
      validation: (rule) => rule.required(),
    }),
    defineField({
      name: 'body',
      title: 'Body',
      type: 'array',
      of: [{type: 'block'}, {type: 'image'}],
      validation: (rule) => rule.required(),
    }),
    defineField({
      name: 'cta',
      title: 'Monetization CTA',
      type: 'object',
      fields: [
        defineField({name: 'label', title: 'Label', type: 'string'}),
        defineField({name: 'href', title: 'URL', type: 'url'}),
        defineField({name: 'intent', title: 'Intent', type: 'string'}),
      ],
    }),
    defineField({
      name: 'verificationNote',
      title: 'Verification note',
      type: 'text',
      rows: 4,
    }),
    defineField({
      name: 'publishedAt',
      title: 'Published at',
      type: 'datetime',
      validation: (rule) => rule.required(),
    }),
  ],
  preview: {
    select: {title: 'title', subtitle: 'locale', media: 'heroImage'},
  },
})
// schemaTypes/index.ts
import {post} from './post'

export const schemaTypes = [post]

GROQ query와 client fetch

목록용 query와 상세용 query는 분리합니다. 목록에서는 본문을 가져오지 않고, 상세에서만 body와 verification note를 가져옵니다. 이 원칙만 지켜도 속도와 캐시 문제가 줄어듭니다.

// src/lib/sanity/queries.ts
export const postsByLocaleQuery = `
  *[
    _type == "post" &&
    locale == $locale &&
    defined(slug.current) &&
    defined(publishedAt)
  ] | order(publishedAt desc) [0...$limit] {
    _id,
    title,
    description,
    "slug": slug.current,
    publishedAt,
    "heroImageUrl": heroImage.asset->url,
    "heroImageAlt": heroImage.alt,
    cta
  }
`

export const postBySlugQuery = `
  *[
    _type == "post" &&
    locale == $locale &&
    slug.current == $slug
  ][0] {
    _id,
    title,
    description,
    "slug": slug.current,
    publishedAt,
    body,
    verificationNote,
    cta,
    "heroImageUrl": heroImage.asset->url,
    "heroImageAlt": heroImage.alt
  }
`
// src/lib/sanity/client.ts
import {createClient} from '@sanity/client'
import {postBySlugQuery, postsByLocaleQuery} from './queries'

export const sanityClient = createClient({
  projectId: process.env.NEXT_PUBLIC_SANITY_PROJECT_ID || '',
  dataset: process.env.NEXT_PUBLIC_SANITY_DATASET || 'production',
  apiVersion: '2026-06-02',
  useCdn: process.env.NODE_ENV === 'production',
})

export async function getPosts(locale: string, limit = 12) {
  return sanityClient.fetch(postsByLocaleQuery, {locale, limit})
}

export async function getPostBySlug(locale: string, slug: string) {
  return sanityClient.fetch(postBySlugQuery, {locale, slug})
}
npm install sanity @sanity/client @sanity/image-url
set NEXT_PUBLIC_SANITY_PROJECT_ID=your_project_id
set NEXT_PUBLIC_SANITY_DATASET=production

실패 사례와 함정

첫 번째 pitfall은 schema를 현재 화면에만 맞추는 것입니다. 처음에는 빠르지만 나중에 다국어, 상품 CTA, 작성자, 리뷰 날짜를 추가할 때 마이그레이션 비용이 커집니다. 매출과 운영에 영향을 주는 필드는 본문에서 분리해야 합니다.

두 번째 pitfall은 query가 너무 큰 것입니다. 목록 페이지에서 모든 body를 가져오면 개발 중에는 티가 나지 않아도 배포 후 빌드 시간과 캐시 효율이 나빠집니다. 카드, 상세, sitemap, 관련 글 query를 나누세요.

세 번째 pitfall은 draft가 공개 페이지에 섞이는 것입니다. publishedAt만으로 충분하지 않은 팀도 많습니다. reviewStatus를 추가하거나 preview dataset과 production dataset을 분리하세요.

네 번째 pitfall은 수익화 CTA를 고정 배너로만 보는 것입니다. 검색 의도에 맞지 않는 CTA는 클릭되지 않습니다. 초보자 글, 비교 글, migration 글, 팀 운영 글은 서로 다른 다음 행동을 가져야 합니다.

rollout checklist

  • title, description, slug, heroImage.alt, publishedAt를 필수로 둔다.
  • 글, FAQ, author, offer, CTA를 필요하면 별도 document로 분리한다.
  • 목록, 상세, sitemap, 관련 글 GROQ query를 분리한다.
  • 다국어 콘텐츠에는 locale과 canonical 정보를 저장한다.
  • 공식 링크, 내부 링크, CTA, 검증 메모를 발행 전 확인한다.
  • GA4, 구매 페이지, 문의 폼, 상담 흐름의 이벤트 이름을 맞춘다.
  • 발행 30일 후 검색 유입, CTA 클릭, 구매, 상담 전환을 보고 개선 메모를 Sanity에 남긴다.

수익화 CTA

Sanity CMS의 목적은 단순히 새 관리 화면을 만드는 것이 아닙니다. 콘텐츠, 증거, 상품, 상담 흐름을 같은 운영 모델로 관리하는 것입니다. ClaudeCodeLab은 기존 Markdown, Contentful, WordPress 콘텐츠를 Sanity schema, GROQ, 품질 검사, 수익화 CTA로 정리하는 작업을 도울 수 있습니다. SEO 글을 템플릿 판매, 교육, 구현 상담으로 연결하고 싶다면 training / consultation에서 실제 repository와 콘텐츠 목록을 기준으로 시작하세요.

#Claude Code #Sanity CMS #Headless CMS #GROQ #Content Ops
무료

무료 PDF: Claude Code 치트시트

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

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

Masa

작성자 소개

Masa

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