← 글 목록

notes

JSON-LD — 구조화 데이터가 뭔지 (쉬운 설명)

검색엔진이 페이지 의미를 읽게 돕는 JSON-LD(구조화 데이터)를 비개발자도 이해할 수 있게 풀어 쓴 개념 노트.

한 줄로

JSON-LD는 검색엔진이 웹페이지 콘텐츠의 「의미」를 schema.org라는 약속된 용어로 기계가 읽게 담아 두는 구조화 데이터 형식이다.

도서관으로 치면, 책표지·목차만으로도 사람은 대충 알 수 있지만, 사서(검색엔진)는 바코드·명찰이 있으면 「이건 요리책이고, 저자는 누구고, 발행일은 언제」를 훨씬 덜 헷갈리고 잡는다. 바코드가 책 내용을 대신하진 않는다. 다만 무엇이 무엇인지를 같은 말로 말해 주는 역할이다.

JSON-LD는 그 이름 그대로 JavaScript Object Notation for Linked Data — JSON으로 쓴 링크드 데이터다. W3C 쪽과도 맞닿아 있는 형식이고, 웹에서 「이 덩어리는 구조화 데이터야」라고 표시할 때 많이 쓰인다.


왜 필요한가 — 사람과 검색엔진이 페이지를 보는 차이

사람은 레이아웃, 큰 제목, 별 아이콘, 「조리 시간 30분」 같은 글씨를 보고 바로 맥락을 잡는다. 「아, 블로그 글이구나」「리뷰네」「이벤트 날짜네」.

검색엔진은 기본적으로 HTML 글자열을 읽어서 해석한다. <div>, <span> 안에 글자가 잔뜩 있어도, 그게 리뷰인지 광고인지, 날짜가 본문인지 사이드바인지를 사람만큼 쉽게 단정하지 못한다. 그래서 「이름표」를 붙여 주면 — 「이 페이지의 이 정보는 Organization(회사·단체)이고, 이름은 ○○다」 — 문맥 파악이 훨씬 명확해진다.

같은 페이지, 사람 vs 검색엔진

이 이름표를 페이지에 붙이는 방법을 넓게는 구조화 데이터(structured data) 라고 부르고, 그중 지금 웹에서 가장 흔히 쓰는 형식이 JSON-LD다.


구조화 데이터란 / schema.org란

구조화 데이터는 「페이지에 보이는 정보를, 기계가 정해진 칸에 맞춰 읽을 수 있게 적어 둔 것」이다. 사람용 문장만 두지 말고, 「타입은 뭐고, 이름은 뭐고, 주소는 뭐」처럼 칸이 있는 기록을 같이 두는 셈이다.

schema.org는 그 칸과 이름표를 모아 둔 약속된 이름표 사전이다. 구글·빙·야후 등이 함께 쓰는 쪽이라, 「Organization = 회사·단체」「Product = 상품」「Article = 글·기사」처럼 서로 다른 사이트도 같은 말로 말할 수 있다. 「스키마」라고 하면 거창해 보이는데, 실무에서는 「이 타입·이 속성 이름으로 쓰자」는 공통 단어장에 가깝다.

schema.org = 약속된 이름표 사전

JSON-LD는 그 이름표를 JSON 한 덩어리로 적어 HTML에 넣는 방식이다. 페이지 본문을 일일이 속성으로 찌르지 않아도 된다.


JSON-LD vs Microdata vs RDFa — 왜 구글이 JSON-LD를 좋아하나

구조화 데이터를 붙이는 방식이 여러 가지다.

구글 Search Central 쪽에서는 대규모로 넣고 고치기 쉽다는 이유로 JSON-LD를 권하는 편이다. 「다른 방식이 틀렸다」가 아니라, 실무에서 다루기 편한 쪽을 밀어 준다에 가깝다. 나는 새 사이트나 Astro 블로그에 넣을 때도 거의 JSON-LD로 간다.


어떻게 붙이나

보통은 HTML의 <head> 안, 또는 <body> 끝에 이런 식으로 한 블록을 넣는다.

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "Organization",
  "name": "예시 회사",
  "url": "https://example.com"
}
</script>

화면에는 안 보인다. 브라우저가 「이건 실행할 JS가 아니라, ld+json 데이터구나」하고 넘기고, 검색엔진 크롤러가 읽어서 해석한다.

JSON-LD는 HTML 안에 한 덩어리로 붙음

자주 나오는 키만 쉽게 풀면 이렇다.

  • @context: 「이 JSON의 단어는 schema.org 사전을 따른다」는 선언. 거의 항상 "https://schema.org" 를 넣는다.
  • @type: 이게 뭔 종류인지 — Organization, Article, Product… 이름표의 종류.
  • @id: 「이 개체의 고유 주소(식별자)」. 같은 회사를 여러 페이지에서 말할 때, URL 같은 걸로 한 존재를 가리키게 할 때 쓴다. 처음엔 없어도 예제는 돌아가지만, 사이트 전체로 키우면 정리에 도움이 된다.

나머지는 @type에 따라 name, url, logo, image 같은 속성(칸) 이 붙는다.


Organization 예시 — 필드가 의미하는 바

회사·브랜드·팀 사이트의 「우리 누구임」을 말할 때 기본이 되는 타입이 Organization이다.

{
  "@context": "https://schema.org",
  "@type": "Organization",
  "name": "블로그",
  "url": "https://example.example",
  "logo": "https://example.example/logo.png",
  "sameAs": [
    "https://www.instagram.com/example",
    "https://blog.example.com"
  ]
}

포인트는 화면에 실제로 있는 이야기와 맞출 것. 로고 URL이 깨져 있거나, 이름만 바꾸고 본문·푸터와 다르면 의미가 없다. 검색엔진은 「이 페이지가 말하는 조직」과 「구조화 데이터가 말하는 조직」이 한통속인지 본다.


리치 결과란 / 순위와의 관계

구조화 데이터가 잘 잡히면, 검색 결과에 별점, 요리 시간, 이벤트 일시, FAQ 펼침 같은 리치 결과(rich result) 후보가 될 수 있다. 평범한 파란 링크 한 줄보다 정보가 풍부해 보이니, 눈에 띄고 클릭될 가능성은 올라갈 수 있다.

다만 구글이 반복해서 말하는 핵심이 있다.

구조화 데이터 → 리치 결과 흐름

자격만 된다고 항상 리치 결과가 뜨는 것도 아니다. 유형별 가이드 충족, 품질, 쿼리·지역 등 여러 조건이 겹친다. 「넣었으니 끝」이 아니라 「넣을 자격은 만들어 둔다」로 보면 마음이 편하다.

사이트 전체 SEO 맥락은 땡큐캠핑 SEO 쪽에 더 있고, 검색·AI 노출 쪽은 GEO(생성형 엔진 최적화) — SEO와 무엇이 다른가, 크롤·인덱싱 신호는 메타 robots 태그 — 정의·지시어·사용법 와 같이 보면 그림이 맞는다.


자주 쓰는 @type — 「이런 페이지에 이런 이름표」

유형별 풀코드는 이 글 범위가 아니다. 다만 이름표가 무엇을 위한 것인지만 짧게.

「블로그면 무조건 BlogPosting만」이 아니다. 홈에는 Organization + WebSite, 글에는 BlogPosting, 상품이면 Product… 페이지가 실제로 무엇인지에 맞추면 된다. 엉뚱한 타입을 붙이면 이름표가 거짓말하는 꼴이다.


여러 개 script / @graph

한 페이지에 JSON-LD <script> 블록이 여러 개 있어도 된다. 예: Organization 하나, BlogPosting 하나.

한 블록 안에 여러 개체를 넣을 때는 @graph 배열로 묶는 패턴도 흔하다. 「이 문맥 안에 A도 있고 B도 있다」를 한 JSON에 모아 두는 방식이다.

{
  "@context": "https://schema.org",
  "@graph": [
    { "@type": "Organization", "name": "…" },
    { "@type": "WebSite", "name": "…", "url": "…" }
  ]
}

처음엔 script를 타입별로 나눠 두고, 나중에 정리하고 싶어질 때 @graph를 봐도 늦지 않다.


주의할 것 — 그리고 테스트

구조화 데이터에서 제일 흔한 사고는 기술 문법 오류보다 「내용이 거짓말」 이다.

  • 화면에 없는 내용을 넣지 않기 — 없는 별점, 가짜 리뷰, 안 보이는 가격·재고.
  • 타입을 끼워 맞추지 않기 — FAQ가 아닌데 FAQPage, 가게가 아닌데 LocalBusiness.
  • 필수에 가까운 칸 빼먹지 않기 — 유형마다 「이게 없으면 리치 결과 후보도 안 됨」인 속성이 있다. (상세는 유형 가이드를 보면 된다. 이 글은 개념이니 목록만 안다.)
  • 배포 후 방치하지 않기 — 로고 URL이 바뀌었는데 JSON-LD만 예전 주소인 경우.

확인 순서는 단순하다.

붙인 뒤 확인하는 순서
  • 사람 눈으로 본문·화면에 있는 말과 JSON이 같은지.
  • 구글 리치 결과 테스트에 URL이나 코드 조각을 넣어 문법·필수값·유형 자격 확인.
  • 실제 사이트에 올린 뒤에는 Search Console(GSC) 에서 해당 리치 결과·구조화 데이터 관련 보고가 쌓이는지 본다.

테스트 도구 이름이 바뀔 수는 있어도, 「미리 검사 → 배포 후 GSC」 흐름은 같다.


블로그(Astro 등)에 넣는 위치 — 개념만

구현 풀코드는 SEO 작업 문서 쪽이 맞고, 개념만 말하면 이렇다.

  • 사이트 공통(Organization, WebSite 등) → 레이아웃 한곳(예: BaseLayout)에 두면 모든 페이지에 따라간다.
  • 글·상품마다 다른 것(BlogPosting, Product 제목·날짜·이미지) → 그 페이지 데이터에서 만들어 그 페이지에만 넣는다.

Astro면 frontmatter·콘텐츠 컬렉션 값을 읽어 <script type="application/ld+json"> 에 JSON.stringify 로 넣는 식이 흔하다. 「어디에 두느냐」만 먼저 정하면, 코드는 그에 맞춰 짧아진다. 민섭 블로그 SEO 정리와 이 글을 같이 보면 「왜 붙이는지 / 어디에 붙이는지」가 한 세트가 된다.


정리

  • JSON-LD = 페이지 의미를 schema.org 이름표로, JSON 한 덩어리로 검색엔진에게 전달하는 형식.
  • Microdata/RDFa처럼 HTML에 속성을 흩뿌리지 않고, application/ld+json script로 분리해 두는 쪽이 유지보수에 유리해서 구글도 밀어 주는 편.
  • 효과의 중심은 리치 결과·문맥 파악. 직접 순위 가산점은 아님.
  • Organization 같은 기본 타입부터, 화면과 같은 말을 쓰는지가 전부다.
  • 붙인 뒤에는 리치 결과 테스트 → GSC로 확인.

이름표는 콘텐츠를 대신하지 않는다. 좋은 글·정확한 상품 정보가 본체고, JSON-LD는 그걸 기계가 덜 헷갈리게 읽는 명찰이다.