이 글은 누구를 위한 것인가
- 구글 검색에서 가격·재고·별점이 검색 결과에 바로 보이게 하고 싶은 팀
- 쇼핑 탭에 상품을 노출하고 싶은 이커머스 마케터
- 상품 페이지 SEO를 기술적으로 구현해야 하는 개발자
들어가며
Schema.org 마크업이 없는 상품 페이지는 구글이 단순 텍스트 페이지로 인식한다. Product 스키마를 추가하면 검색 결과에 가격, 재고 상태, 별점이 표시되어 CTR이 크게 높아진다.
이 글은 bluefoxdev.kr의 이커머스 SEO 기술 가이드 를 참고하여 작성했습니다.
1. 필수 Schema 유형
[이커머스 Schema.org 우선순위]
1. Product (상품 페이지)
필수: name, image, description, sku
권장: brand, offers, aggregateRating, review
→ Google 쇼핑 탭 노출
2. BreadcrumbList (카테고리 경로)
→ 검색 결과에 경로 표시
3. FAQPage (상품 FAQ)
→ 검색 결과에 FAQ 아코디언
4. Review + AggregateRating
→ 별점 스니펫
5. Organization (브랜드)
→ 브랜드 패널
2. Product JSON-LD 구현
// Next.js에서 상품 페이지 구조화 데이터 생성
import type { Product } from '@/types';
export function generateProductSchema(product: Product): object {
return {
"@context": "https://schema.org",
"@type": "Product",
"name": product.name,
"description": product.description,
"image": product.images.map(img => img.url),
"sku": product.sku,
"mpn": product.mpn || product.sku,
"brand": {
"@type": "Brand",
"name": product.brand
},
"offers": {
"@type": "Offer",
"url": `https://myshop.com/products/${product.slug}`,
"priceCurrency": "KRW",
"price": product.salePrice || product.price,
"priceValidUntil": product.salePriceEnd || "2027-12-31",
"availability": product.stockQty > 0
? "https://schema.org/InStock"
: "https://schema.org/OutOfStock",
"itemCondition": "https://schema.org/NewCondition",
"seller": {
"@type": "Organization",
"name": "My Shop"
}
},
"aggregateRating": product.reviewCount > 0 ? {
"@type": "AggregateRating",
"ratingValue": product.averageRating.toFixed(1),
"reviewCount": product.reviewCount,
"bestRating": "5",
"worstRating": "1"
} : undefined,
"review": product.reviews?.slice(0, 5).map(review => ({
"@type": "Review",
"reviewRating": {
"@type": "Rating",
"ratingValue": review.rating,
"bestRating": "5"
},
"author": {
"@type": "Person",
"name": review.authorName
},
"reviewBody": review.content,
"datePublished": review.createdAt
}))
};
}
export function generateBreadcrumbSchema(breadcrumbs: {name: string; url: string}[]): object {
return {
"@context": "https://schema.org",
"@type": "BreadcrumbList",
"itemListElement": breadcrumbs.map((crumb, index) => ({
"@type": "ListItem",
"position": index + 1,
"name": crumb.name,
"item": `https://myshop.com${crumb.url}`
}))
};
}
// page.tsx에서 사용
export default async function ProductPage({ params }: { params: { slug: string } }) {
const product = await getProduct(params.slug);
const productSchema = generateProductSchema(product);
const breadcrumbSchema = generateBreadcrumbSchema([
{ name: "홈", url: "/" },
{ name: product.category, url: `/category/${product.categorySlug}` },
{ name: product.name, url: `/products/${product.slug}` }
]);
return (
<>
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(productSchema) }}
/>
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(breadcrumbSchema) }}
/>
{/* 상품 페이지 콘텐츠 */}
</>
);
}
3. FAQ 스키마 (상품 Q&A)
export function generateFAQSchema(faqs: {question: string; answer: string}[]): object {
return {
"@context": "https://schema.org",
"@type": "FAQPage",
"mainEntity": faqs.map(faq => ({
"@type": "Question",
"name": faq.question,
"acceptedAnswer": {
"@type": "Answer",
"text": faq.answer
}
}))
};
}
// 상품 FAQ 예시
const productFAQs = [
{
question: "이 제품의 반품 기간은 얼마나 되나요?",
answer: "수령 후 7일 이내 반품이 가능합니다. 단, 제품 개봉 후에는 반품이 어려울 수 있습니다."
},
{
question: "해외 배송이 가능한가요?",
answer: "현재 국내 배송만 지원하고 있습니다. 해외 배송은 준비 중입니다."
}
];
4. 검증 및 모니터링
[Schema 검증 도구]
1. Google Rich Results Test: search.google.com/test/rich-results
2. Schema.org Validator: validator.schema.org
3. Google Search Console → 풍부한 검색 결과 리포트
[검증 체크리스트]
□ price와 priceCurrency 모두 있음
□ availability 값이 Schema.org URL 형식
□ image가 최소 하나 이상
□ 별점이 있으면 reviewCount도 있음
□ 실제 페이지와 데이터 일치 (가격 조작 금지)
[모니터링 지표]
- 리치 스니펫 노출 수 (Search Console)
- 구조화 데이터 오류 수
- 쇼핑 탭 클릭 수
마무리
Schema.org 마크업은 구현 비용 대비 SEO 효과가 매우 높다. 상품 페이지에 Product + Offer + AggregateRating을 추가하면 리치 스니펫 노출로 CTR이 20-30% 이상 향상될 수 있다. Google Search Console에서 구조화 데이터 리포트를 주기적으로 확인하고 오류를 수정하는 것이 중요하다.