docs(10_Wiki): 위키 전체 재구성 — Topic_* 폴더를 4개 카테고리로 통합 + 대규모 중복 제거
Topic_Agent/Topic_Blog/Topics/Topics_Biz/Topics_Meeting/Topics_Rag의 마크다운 지식 문서를 Topic_General/Topic_Programming/Topic_Graphic/Topic_Business 4개 카테고리로 재분류. - 중복 제거: frontmatter의 status:duplicate/merged + duplicate_of/redirect_to 필드로 자기 자신을 중복으로 선언한 리다이렉트 stub 1032개 제거, 완전 동일 내용 파일 472개 제거, 동일 파일명·다른 내용 충돌 시 더 큰(완전한) 버전만 유지(162개 제거) — 총 1639개 중복 제거. - 분류: 폴더 단위로 명확한 항목(AI_and_ML/Coding/Architecture 등 → Programming, Comfyui/Visual_Effects → Graphic, Topics_Biz/Topics_Meeting/사업 등 → Business, Poetic_Blog_Writing/창의성/Game_Design 등 → General)은 폴더 우선순위로, 나머지 혼재 폴더(Topic_Agent/Topic_Blog/Topics 루트/Thinking & Reasoning/Other/UI_UX_Assets)는 title/tags 키워드 스코어링으로 파일 단위 분류(불명확한 경우 General로 폴백). 원본 폴더명은 "From_*" 서브폴더로 보존해 추적 가능성 유지. - 최종 배치: Programming 2784 / General 1608 / Graphic 285 / Business 249 = 4926개 문서. - 에이전트 운영 상태(.astra/.agent/.obsidian/sessions/memory/_company/docs/lessons/_shared/src)는 지식 콘텐츠가 아니므로 재분류 대상에서 제외하고 원위치 유지. - Topics/Topic_email(상위 보호 폴더 Topic_email과 파일명 100% 중복) 삭제 — 보호 폴더 자체는 미변경. - 완전히 비게 된 Topic_Agent/Topic_Blog/Topics_Biz/Topics_Rag 폴더 제거.
This commit is contained in:
@@ -0,0 +1,213 @@
|
||||
---
|
||||
id: wiki-2026-0508-json-ld-structured-data
|
||||
title: JSON-LD Structured Data
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [JSON-LD, Structured Data, Schema.org JSON-LD]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.9
|
||||
verification_status: applied
|
||||
tags: [seo, json-ld, schema-org, structured-data, web]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
tech_stack:
|
||||
language: javascript
|
||||
framework: schema.org
|
||||
---
|
||||
|
||||
# JSON-LD Structured Data
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 JSON-LD = 검색엔진에게 페이지 의미를 직접 말해주는 메타 데이터 레이어"**. HTML 마크업과 분리된 `<script type="application/ld+json">` 블록으로 Schema.org vocabulary를 사용해 entity, relation, property를 선언한다. Google이 권장하는 structured data 형식이며 rich snippet/knowledge panel/AI Overviews 노출의 입장권.
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 왜 JSON-LD인가
|
||||
- **분리성**: HTML rendering과 독립 — 마크업 변경 없이 추가 가능.
|
||||
- **Google 권장**: Microdata/RDFa보다 우선순위 높음 (2026 기준).
|
||||
- **AI 친화적**: LLM-powered search (Perplexity, ChatGPT Search, Google AI Overviews)가 entity graph 추출에 활용.
|
||||
- **유지보수**: Template engine에서 server-side 생성 쉬움.
|
||||
|
||||
### 매 핵심 vocabulary
|
||||
- `@context`: 보통 `"https://schema.org"`.
|
||||
- `@type`: Article, Product, Organization, BreadcrumbList, FAQPage, Recipe 등.
|
||||
- `@id`: entity의 canonical URI (graph 연결용).
|
||||
- `@graph`: 같은 페이지 내 다중 entity 묶음.
|
||||
|
||||
### 매 응용
|
||||
1. E-commerce → Product + Offer + AggregateRating.
|
||||
2. 미디어/블로그 → Article + Author(Person) + Publisher(Organization).
|
||||
3. 로컬 비즈니스 → LocalBusiness + Address + OpeningHours.
|
||||
4. FAQ/HowTo → FAQPage / HowTo (rich snippet 가시성 매우 높음).
|
||||
5. SaaS → SoftwareApplication + AggregateRating.
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### Article schema (블로그/뉴스)
|
||||
```html
|
||||
<script type="application/ld+json">
|
||||
{
|
||||
"@context": "https://schema.org",
|
||||
"@type": "Article",
|
||||
"headline": "JSON-LD 완전 정복",
|
||||
"image": ["https://example.com/cover.jpg"],
|
||||
"datePublished": "2026-05-10T08:00:00+09:00",
|
||||
"dateModified": "2026-05-10T08:00:00+09:00",
|
||||
"author": {
|
||||
"@type": "Person",
|
||||
"name": "홍길동",
|
||||
"url": "https://example.com/author/hong"
|
||||
},
|
||||
"publisher": {
|
||||
"@type": "Organization",
|
||||
"name": "Example",
|
||||
"logo": {
|
||||
"@type": "ImageObject",
|
||||
"url": "https://example.com/logo.png"
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
### Product + Offer (E-commerce)
|
||||
```html
|
||||
<script type="application/ld+json">
|
||||
{
|
||||
"@context": "https://schema.org",
|
||||
"@type": "Product",
|
||||
"name": "Mechanical Keyboard X1",
|
||||
"image": "https://example.com/x1.jpg",
|
||||
"sku": "X1-BLK",
|
||||
"brand": { "@type": "Brand", "name": "Acme" },
|
||||
"offers": {
|
||||
"@type": "Offer",
|
||||
"url": "https://example.com/p/x1",
|
||||
"priceCurrency": "KRW",
|
||||
"price": "189000",
|
||||
"availability": "https://schema.org/InStock",
|
||||
"itemCondition": "https://schema.org/NewCondition"
|
||||
},
|
||||
"aggregateRating": {
|
||||
"@type": "AggregateRating",
|
||||
"ratingValue": "4.7",
|
||||
"reviewCount": "412"
|
||||
}
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
### BreadcrumbList
|
||||
```json
|
||||
{
|
||||
"@context": "https://schema.org",
|
||||
"@type": "BreadcrumbList",
|
||||
"itemListElement": [
|
||||
{ "@type": "ListItem", "position": 1, "name": "Home", "item": "https://example.com/" },
|
||||
{ "@type": "ListItem", "position": 2, "name": "Blog", "item": "https://example.com/blog" },
|
||||
{ "@type": "ListItem", "position": 3, "name": "JSON-LD" }
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### FAQPage (rich snippet 효과 큼)
|
||||
```json
|
||||
{
|
||||
"@context": "https://schema.org",
|
||||
"@type": "FAQPage",
|
||||
"mainEntity": [{
|
||||
"@type": "Question",
|
||||
"name": "JSON-LD를 어디에 넣어야 하나요?",
|
||||
"acceptedAnswer": {
|
||||
"@type": "Answer",
|
||||
"text": "<head> 또는 <body> 어디든 가능. <head> 권장."
|
||||
}
|
||||
}]
|
||||
}
|
||||
```
|
||||
|
||||
### Next.js 13+ App Router 동적 생성
|
||||
```tsx
|
||||
// app/blog/[slug]/page.tsx
|
||||
export default async function Page({ params }) {
|
||||
const post = await getPost(params.slug);
|
||||
const jsonLd = {
|
||||
"@context": "https://schema.org",
|
||||
"@type": "Article",
|
||||
headline: post.title,
|
||||
datePublished: post.publishedAt,
|
||||
author: { "@type": "Person", name: post.author },
|
||||
};
|
||||
return (
|
||||
<>
|
||||
<script
|
||||
type="application/ld+json"
|
||||
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
|
||||
/>
|
||||
<article>{/* content */}</article>
|
||||
</>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
### @graph로 다중 entity 연결
|
||||
```json
|
||||
{
|
||||
"@context": "https://schema.org",
|
||||
"@graph": [
|
||||
{ "@type": "Organization", "@id": "https://example.com/#org", "name": "Example" },
|
||||
{ "@type": "WebSite", "@id": "https://example.com/#site", "publisher": { "@id": "https://example.com/#org" } },
|
||||
{ "@type": "WebPage", "@id": "https://example.com/page#webpage", "isPartOf": { "@id": "https://example.com/#site" } }
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 검증 (Node 스크립트)
|
||||
```js
|
||||
// scripts/validate-jsonld.mjs
|
||||
import { readFileSync } from "fs";
|
||||
const html = readFileSync(process.argv[2], "utf8");
|
||||
const matches = html.matchAll(/<script type="application\/ld\+json">([\s\S]*?)<\/script>/g);
|
||||
for (const m of matches) {
|
||||
try { JSON.parse(m[1]); console.log("OK"); }
|
||||
catch (e) { console.error("INVALID:", e.message); process.exit(1); }
|
||||
}
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Approach |
|
||||
|---|---|
|
||||
| 단일 entity 페이지 | 단순 `@type` 객체 |
|
||||
| 다중 entity (sitelinks 노리기) | `@graph` 배열 |
|
||||
| CMS/headless | 빌드 시 SSG/SSR로 inject |
|
||||
| 동적 콘텐츠 (가격 변동) | SSR로 매 요청 생성 |
|
||||
|
||||
**기본값**: SSR로 page-level JSON-LD 생성 + Google Rich Results Test로 검증.
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[SEO]]
|
||||
- 응용: [[Knowledge Graph|Knowledge-Graph]], [[AI-Search-Optimization]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: schema 자동 생성 (페이지 콘텐츠 → JSON-LD), 누락 type 추천, validation 에러 해석.
|
||||
**언제 X**: Schema.org spec의 정확성 검증 (LLM이 deprecated property 추천 가능 — 항상 Google Rich Results Test로 cross-check).
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **Hidden content**: 페이지에 없는 정보를 JSON-LD에만 — Google penalty.
|
||||
- **잘못된 @type**: Article인데 Product로 — 무시됨.
|
||||
- **다중 동일 type**: 한 페이지에 Article 3개 — 어떤 게 main인지 모호.
|
||||
- **수동 매번 작성**: template/helper 없이 — 일관성 깨짐, typo.
|
||||
- **검증 누락**: production 배포 후 무효 JSON 발견.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (Google Search Central docs, schema.org 2026).
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — 매 format, Next.js App Router 패턴, @graph 추가 |
|
||||
Reference in New Issue
Block a user