Claude Code로 블로그 뚝딱 만들기 (5편: OG 이미지, SEO, Analytics)
Medium Priority 다 해봐. OG 이미지 자동 생성, JSON-LD, Analytics, Callout, 읽기 진행바까지.
#claude-code#nextjs#blog#seo#og-image
📚
Claude Code로 블로그 뚝딱 만들기 시리즈
(7편)- 1Claude Code로 블로그 뚝딱 만들기 (1편: 설계)
- 2Claude Code로 블로그 뚝딱 만들기 (2편: 커스터마이징)
- 3Claude Code로 블로그 뚝딱 만들기 (3편: AI 글쓰기 시스템)
- 4Claude Code로 블로그 뚝딱 만들기 (4편: 검색, RSS, 목차, Draft)
- 5Claude Code로 블로그 뚝딱 만들기 (5편: OG 이미지, SEO, Analytics)
- 6Claude Code로 블로그 뚝딱 만들기 (6편: 댓글, 태그, UX 개선)
- 7Claude Code로 블로그 뚝딱 만들기 (7편: 인기글 랭킹과 Analytics)
다 해봐
4편에서 roadmap.md 만들어놨다. Medium Priority가 5개 남아있었다.
그래서 이렇게 시켰다:
plaintext
@roadmap.md 진행해"다 해봐"라고 했다.
걔가 5개 태스크 만들더니 순서대로 진행하기 시작했다.
1. OG 이미지 자동 생성
SNS 공유할 때 썸네일 이미지. @vercel/og 쓰면 Edge Function에서 동적으로 만들 수 있다.
typescript
// src/app/api/og/route.tsx
import { ImageResponse } from 'next/og';
export const runtime = 'edge';
export async function GET(request: NextRequest) {
const title = searchParams.get('title') || '뇌 용량 확보용';
const category = searchParams.get('category') || '';
return new ImageResponse(
<div style={{ /* 스타일 */ }}>
{category && <span>{category}</span>}
<div>{title}</div>
<span>뇌 용량 확보용</span>
</div>,
{ width: 1200, height: 630 }
);
}메타데이터에 연결하면 끝이다.
typescript
const ogImageUrl = `${SITE_URL}/api/og?title=${encodeURIComponent(post.title)}&category=${encodeURIComponent(category)}`;
return {
openGraph: {
images: [{ url: ogImageUrl, width: 1200, height: 630 }],
},
};이제 /api/og?title=테스트 치면 이미지가 나온다.
2. JSON-LD 스키마
구글이 글 구조를 이해하게 해주는 마크업이다.
typescript
// src/components/JsonLd.tsx
export function ArticleJsonLd({ title, description, publishedTime, url, category, tags }) {
const jsonLd = {
'@context': 'https://schema.org',
'@type': 'BlogPosting',
headline: title,
datePublished: publishedTime,
author: { '@type': 'Person', name: '서상원' },
// ...
};
return (
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
/>
);
}글 페이지에 넣으면 된다.
tsx
<ArticleJsonLd
title={post.title}
description={post.description}
publishedTime={post.date}
url={url}
category={category}
tags={post.tags}
/>3. Vercel Analytics
제일 간단했다.
bash
npm install @vercel/analyticslayout.tsx에 한 줄 추가.
tsx
import { Analytics } from "@vercel/analytics/next";
// body 안에
<Analytics />Vercel 배포하면 대시보드에서 바로 보인다.
4. Callout 컴포넌트
문서에서 강조할 때 쓰는 박스. NOTE, WARNING, TIP 같은 거.
typescript
// src/components/Callout.tsx
type CalloutType = 'note' | 'warning' | 'tip' | 'danger' | 'info';
export default function Callout({ type = 'note', title, children }) {
const config = calloutConfig[type]; // 타입별 색상, 아이콘
return (
<div className={`${config.bgClass} ${config.borderClass}`}>
<span>{config.icon} {title}</span>
<div>{children}</div>
</div>
);
}MDX에서 이렇게 쓴다:
mdx
<Callout type="tip" title="팁">
이런 식으로 쓰면 된다.
</Callout>
<Callout type="warning">
주의할 점도 적을 수 있다.
</Callout>타입은 5개: note, warning, tip, danger, info
5. 읽기 진행 표시기
스크롤하면 상단에 바가 차오르는 거.
typescript
// src/components/ReadingProgress.tsx
'use client';
export default function ReadingProgress() {
const [progress, setProgress] = useState(0);
useEffect(() => {
const updateProgress = () => {
const scrollTop = window.scrollY;
const docHeight = document.documentElement.scrollHeight - window.innerHeight;
setProgress((scrollTop / docHeight) * 100);
};
window.addEventListener('scroll', updateProgress, { passive: true });
return () => window.removeEventListener('scroll', updateProgress);
}, []);
return (
<div className="fixed top-0 left-0 right-0 h-1">
<div style={{ width: `${progress}%` }} />
</div>
);
}글 페이지에 넣으면 끝.
빌드 확인
다 끝나고 빌드 돌렸다.
plaintext
✓ Compiled successfully
✓ Generating static pages (14/14)문제없다.
roadmap 업데이트
Claude Code가 알아서 roadmap.md 업데이트했다.
markdown
## ✅ Done
### 2026-02-04
- [x] OG 이미지 자동 생성
- [x] JSON-LD 스키마
- [x] Vercel Analytics
- [x] Callout 컴포넌트
- [x] 읽기 진행 표시기Medium Priority가 비었다. Low Priority만 남았다.
5편 정리
이번에 한 것:
- OG 이미지 →
@vercel/og로 동적 생성 - JSON-LD → SEO용 구조화 데이터
- Analytics → Vercel Analytics 연동
- Callout → MDX용 강조 컴포넌트
- 읽기 진행바 → 스크롤 기반 프로그레스
"다 해봐" 한 마디에 5개 기능이 추가됐다.
Low Priority는 댓글(Giscus), 태그 아카이브, Back to Top 버튼 정도. 필요하면 또 "다 해봐" 하면 될 것 같다.