정의
내 페이지가 "무엇에 관한 것인지"(제품인지, 가격이 얼마인지, 이 글의 저자·날짜가 무엇인지)를 검색엔진이 확실히 알아듣게 해서, 구글 검색 결과에 별점·가격·빵부스러기 경로 같은 리치 결과로 나오게 하고 싶을 때 쓰는 방식이다.
JSON-LD(JavaScript Object Notation for Linked Data)는 그 의미 정보를 HTML 안에 <script type="application/ld+json"> 태그로 넣는 데이터 형식이다. schema.org(구글·MS 등이 함께 정한 표준 어휘 사전)의 단어로 WebPage(웹페이지), Product(제품), Offer(판매 조건·가격), BreadcrumbList(빵부스러기 내비게이션 경로) 같은 타입을 적어두면, 검색 엔진·크롤러(웹을 훑어 색인하는 봇)가 사람이 아니라 기계로도 페이지 의미를 정확히 읽어낸다.
왜 필요한가
가격 페이지·제품 상세는 화면에 글자로만 보여줘서는 기계가 "이게 플랜 이름이고, 저게 가격이고, 통화는 원이고, 이 페이지는 이 카테고리 아래에 있다"는 관계를 안정적으로 뽑아내기 어렵다. JSON-LD는 이 관계를 대놓고 명시한다. 화면 UI가 client component(브라우저에서 실행되는 React 컴포넌트)여도, **서버에서 실행되는 page.tsx**에서 빌더 함수로 이 데이터 뭉치(graph)를 만들면 SEO용 데이터와 화면 UI를 깔끔히 분리할 수 있다.
동작 원리
*JsonLd.ts같은 순수 빌더에서@context,@graph,@type,@id조립.- 사이트 전역 Organization/WebSite는
@id참조만 하고 페이지마다 전체 재정의하지 않음. - locale별 canonical URL·이름 반영.
page.tsx(Server Component)에서:
- Offer는 실제 판매 가격이 있는 tier만; 문의형 enterprise tier는 제외.
실무 적용
- 정적 가격 테이블·i18n 문자열을 빌더 입력으로 — 런타임 DB 없이도 결정적 graph 생성.
- Vitest로
@graph길이, Offer 개수, 필수@typeassertion. - 게스트/로그인 UI 분기는 client; JSON-LD는 공개 정보 기준으로 서버에서만 생성.
트레이드오프
| 선택 | 이득 | 비용 |
|---|---|---|
| Server script inject | 크롤러가 초기 HTML에서 즉시 파싱 | 빌더·테스트 유지 |
| Client-only graph | UI와 한 파일 | 크롤러·SSR 이점 감소 |
| 거대 single graph | 한 script로 관계 표현 | 페이지별 유지보수 부담 |
사용하면 안 되는 경우
- 비공개·개인화 데이터를 graph에 넣어야 하는 경우(공개 JSON-LD 부적합).
- 가격이 클라이언트에서만 결정되고 서버가 알 수 없는 경우 — graph가 stale·부정확해짐.
흔한 실수
JSON.stringifysanitize 없이 user-controlled 문자열 삽입.- Organization/WebSite를 매 페이지마다 중복 정의해 graph 불일치.
- UI client 컴포넌트 안에서만 graph 생성 — 초기 HTML에 없음.
- 문의형 플랜에 가격 없는 Offer 포함.
관련 개념
- single-source-of-truth-content-metadata — frontmatter·메타 SSOT
- critical-rendering-path — script 파싱과 렌더(일반적으로 non-blocking)