بنقرة واحدة
structured-data
Schema.org 구조화된 데이터(JSON-LD) 구현 스킬. Article, FAQPage, BreadcrumbList, HowTo 등 다양한 스키마를 블로그에 적용합니다.
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
القائمة
Schema.org 구조화된 데이터(JSON-LD) 구현 스킬. Article, FAQPage, BreadcrumbList, HowTo 등 다양한 스키마를 블로그에 적용합니다.
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
استنادا إلى تصنيف SOC المهني
변경된 코드를 분석하여 관심사별로 그룹화하고, 각 그룹을 별도로 git add 하여 단계별 커밋을 수행합니다.
Git 커밋 내역을 분석하여 Obsidian 형식의 개발 기록 마크다운 자동 생성. "오늘 커밋 정리", "개발 기록 작성", "커밋 분석", "작업 로그" 요청 시 트리거. 커밋 메시지, 변경 파일, diff를 분석하여 frontmatter 메타데이터와 기술 개념 설명이 포함된 체계적인 문서 생성 후 Obsidian MCP로 저장.
AEO(Answer Engine Optimization) 및 GEO(Generative Engine Optimization) 최적화 스킬. AI 검색 엔진과 생성형 AI가 콘텐츠를 이해하고 인용할 수 있도록 최적화합니다.
블로그 SEO(검색 엔진 최적화) 전문 스킬. 메타데이터, sitemap, robots.txt, 구조화된 데이터, 캐노니컬 URL 등 기술적 SEO 구현을 담당합니다.
웹 성능 최적화 스킬. Core Web Vitals(LCP, FID, CLS, INP) 개선, 이미지/폰트 최적화, 코드 스플리팅, 캐싱 전략을 담당합니다.
| name | structured-data |
| description | Schema.org 구조화된 데이터(JSON-LD) 구현 스킬. Article, FAQPage, BreadcrumbList, HowTo 등 다양한 스키마를 블로그에 적용합니다. |
| triggers | ["JSON-LD 추가해줘","구조화 데이터 추가","스키마 마크업","리치 결과 최적화"] |
Schema.org 기반 JSON-LD 구조화된 데이터를 구현하여 Google 리치 결과(Rich Results)에 노출되도록 최적화합니다.
// components/schema/BlogPostingSchema.tsx
interface BlogPostingSchemaProps {
title: string;
description: string;
slug: string;
category: string;
createdAt: string;
updatedAt?: string;
author: string;
thumbnailImage?: string;
keywords?: string[];
wordCount?: number;
}
export function BlogPostingSchema(props: BlogPostingSchemaProps) {
const schema = {
'@context': 'https://schema.org',
'@type': 'BlogPosting',
headline: props.title,
description: props.description,
image: props.thumbnailImage,
datePublished: props.createdAt,
dateModified: props.updatedAt || props.createdAt,
author: {
'@type': 'Person',
name: props.author,
url: 'https://yourdomain.com/me',
},
publisher: {
'@type': 'Organization',
name: 'HM Blog',
logo: {
'@type': 'ImageObject',
url: 'https://yourdomain.com/logo.png',
},
},
mainEntityOfPage: {
'@type': 'WebPage',
'@id': `https://yourdomain.com/${props.category}/${props.slug}`,
},
keywords: props.keywords?.join(', '),
wordCount: props.wordCount,
articleSection: props.category,
inLanguage: 'ko-KR',
};
return (
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(schema) }}
/>
);
}
// components/schema/BreadcrumbSchema.tsx
interface Breadcrumb {
name: string;
url: string;
}
export function BreadcrumbSchema({ items }: { items: Breadcrumb[] }) {
const schema = {
'@context': 'https://schema.org',
'@type': 'BreadcrumbList',
itemListElement: items.map((item, index) => ({
'@type': 'ListItem',
position: index + 1,
name: item.name,
item: item.url,
})),
};
return (
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(schema) }}
/>
);
}
// 사용 예시
<BreadcrumbSchema
items={[
{ name: 'Home', url: 'https://yourdomain.com' },
{ name: 'Tech', url: 'https://yourdomain.com/tech' },
{ name: 'Next.js 가이드', url: 'https://yourdomain.com/tech/nextjs-guide' },
]}
/>
// components/schema/FAQSchema.tsx
interface FAQ {
question: string;
answer: string;
}
export function FAQSchema({ faqs }: { faqs: FAQ[] }) {
const schema = {
'@context': 'https://schema.org',
'@type': 'FAQPage',
mainEntity: faqs.map((faq) => ({
'@type': 'Question',
name: faq.question,
acceptedAnswer: {
'@type': 'Answer',
text: faq.answer,
},
})),
};
return (
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(schema) }}
/>
);
}
// components/schema/HowToSchema.tsx
interface HowToStep {
name: string;
text: string;
image?: string;
}
interface HowToSchemaProps {
name: string;
description: string;
steps: HowToStep[];
totalTime?: string; // ISO 8601 duration (예: "PT30M")
}
export function HowToSchema(props: HowToSchemaProps) {
const schema = {
'@context': 'https://schema.org',
'@type': 'HowTo',
name: props.name,
description: props.description,
totalTime: props.totalTime,
step: props.steps.map((step, index) => ({
'@type': 'HowToStep',
position: index + 1,
name: step.name,
text: step.text,
image: step.image,
})),
};
return (
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(schema) }}
/>
);
}
// components/schema/WebSiteSchema.tsx
export function WebSiteSchema() {
const schema = {
'@context': 'https://schema.org',
'@type': 'WebSite',
name: 'HM Blog',
url: 'https://yourdomain.com',
description: 'Tech & Life 이야기를 전합니다.',
inLanguage: 'ko-KR',
potentialAction: {
'@type': 'SearchAction',
target: {
'@type': 'EntryPoint',
urlTemplate: 'https://yourdomain.com/search?q={search_term_string}',
},
'query-input': 'required name=search_term_string',
},
};
return (
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(schema) }}
/>
);
}
// components/schema/PersonSchema.tsx
export function PersonSchema() {
const schema = {
'@context': 'https://schema.org',
'@type': 'Person',
name: '홍길동',
jobTitle: '시니어 프론트엔드 개발자',
url: 'https://yourdomain.com/me',
image: 'https://yourdomain.com/profile.jpg',
description: 'Tech & Life 블로그를 운영하는 개발자입니다.',
sameAs: [
'https://github.com/username',
'https://linkedin.com/in/username',
'https://twitter.com/username',
],
knowsAbout: ['React', 'Next.js', 'TypeScript', 'Web Development'],
};
return (
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(schema) }}
/>
);
}
// components/schema/OrganizationSchema.tsx
export function OrganizationSchema() {
const schema = {
'@context': 'https://schema.org',
'@type': 'Organization',
name: 'HM Blog',
url: 'https://yourdomain.com',
logo: 'https://yourdomain.com/logo.png',
sameAs: [
'https://github.com/username',
],
contactPoint: {
'@type': 'ContactPoint',
email: 'contact@yourdomain.com',
contactType: 'customer service',
},
};
return (
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(schema) }}
/>
);
}
// components/schema/index.tsx
import { BlogPostingSchema } from './BlogPostingSchema';
import { BreadcrumbSchema } from './BreadcrumbSchema';
import { FAQSchema } from './FAQSchema';
interface PostSchemaProps {
post: Post;
faqs?: FAQ[];
}
export function PostStructuredData({ post, faqs }: PostSchemaProps) {
const breadcrumbs = [
{ name: 'Home', url: 'https://yourdomain.com' },
{ name: post.category === 'tech' ? 'Tech' : 'Life', url: `https://yourdomain.com/${post.category}` },
{ name: post.title, url: `https://yourdomain.com/${post.category}/${post.slug}` },
];
return (
<>
<BlogPostingSchema
title={post.title}
description={post.summary}
slug={post.slug}
category={post.category}
createdAt={post.createdAt}
updatedAt={post.updatedAt}
author="홍길동"
thumbnailImage={post.thumbnailImage}
keywords={post.keywords}
/>
<BreadcrumbSchema items={breadcrumbs} />
{faqs && faqs.length > 0 && <FAQSchema faqs={faqs} />}
</>
);
}
// app/page.tsx
<WebSiteSchema />
<OrganizationSchema />
// app/[category]/[slug]/page.tsx
<PostStructuredData post={post} />
// app/me/page.tsx
<PersonSchema />
https://search.google.com/test/rich-results
https://validator.schema.org/