2P by GN⁺ | ★ favorite | 댓글 1개
  • 개인 웹사이트도 구조화 데이터를 넣으면 크롤러가 페이지와 인물, 글의 관계를 더 잘 이해하고 링크 미리보기와 검색 노출 품질을 개선할 수 있음
  • 구현은 <head> 안의 <script type="application/ld+json">@contextSchema.org로 지정하고, @graphWebSite, Person, BlogPosting 같은 노드를 배치하는 방식임
  • 같은 @id를 쓰면 웹 크롤러가 여러 페이지의 노드 속성을 병합할 수 있지만, 한 페이지만 읽는 스크레이퍼나 LLM은 병합하지 않는다는 차이가 있음
  • 루트 페이지에는 WebSite, ProfilePage, Person을 기본으로 두고, 블로그·프로젝트·목록 페이지에는 Blog, BlogPosting, SoftwareApplication, CollectionPage, BreadcrumbList를 성격에 맞게 추가함
  • PersonsameAs, 페이지의 breadcrumb, 글의 image·license·날짜 필드는 인물 식별, 검색 결과 경로, 글 미리보기, 사용 조건, 최신성 판단에 직접 쓰임

JSON-LD의 역할과 기본 구조

  • JSON-LD는 JSON Linked Data의 약자로, 웹페이지에 구조화 데이터를 추가하는 형식임
  • 크롤러가 사이트의 의미 구조를 이해하는 데 도움을 주며, 더 풍부한 링크 미리보기와 잠재적인 검색 순위 개선에 기여할 수 있음
  • 페이지에 추가할 때는 <head> 섹션 안에 다음 형태의 스크립트를 넣음
    • <script type="application/ld+json">는 MIME 타입을 application/ld+json으로 선언함
    • 이 타입이 지정되면 브라우저의 JavaScript 엔진은 실행하지 않음
    • Googlebot 같은 특수 크롤러가 해당 요소를 찾아 내용을 파싱함

@context, @graph, 노드 ID

  • @context는 JSON-LD 데이터가 따르는 문맥을 지정하며, 웹 크롤러는 Schema.org를 표준으로 사용함
  • Schema.org는 JSON에서 사용할 수 있는 유효한 키-값 쌍을 정의함
  • JSON-LD 문서는 라벨이 붙은 방향 그래프로 볼 수 있고, 데이터는 @graph 아래에 저장됨
  • 그래프에는 여러 노드가 들어가며, 노드들은 방향성 있는 연결로 이어짐
  • 각 노드는 다음 요소로 구성됨
    • @type: 노드가 무엇인지 나타냄. 예: WebSite, SoftwareApplication
    • @id: 보통 URL 끝에 고유한 해시 값을 붙인 노드의 식별자
    • 속성: 노드의 특성을 나타내는 키-값 쌍
  • 웹 크롤러는 같은 @id를 공유하는 노드의 속성을 여러 페이지에 걸쳐 병합할 수 있음
  • 단일 페이지만 읽는 스크레이퍼나 LLM은 속성을 병합하지 않으므로, 여러 페이지에 JSON-LD를 재사용할 때 이 차이를 고려해야 함
  • @id#website처럼 노드를 고유하게 식별하는 해시를 URL 뒤에 붙이는 방식이 권장됨

사이트와 페이지를 설명하는 노드

  • WebSite

    • WebSite는 사이트의 메타데이터를 담고, 크롤러가 사이트를 어떻게 표시할지 판단하는 데 힌트를 제공함
    • 루트 페이지에는 url, name, alternateName, description, inLanguage, publisher, image 같은 속성을 포함한 상세 버전을 둘 수 있음
    • 모든 페이지에 전체 WebSite 노드를 넣을 필요는 없음
    • 도메인의 루트 페이지는 상세하게 작성하고, 다른 페이지에는 @type, @id, url, name만 포함한 축약 버전도 충분함
    • 축약 버전은 단일 페이지만 읽는 크롤러가 사이트 이름을 올바르게 파악하는 데 필요한 맥락을 제공함
  • WebPage

    • WebPage는 현재 페이지 자체, 즉 HTML 물리 페이지를 나타냄
    • BlogPosting 같은 콘텐츠 유형과 구분해야 하며, WebPage는 해당 콘텐츠를 담고 있는 페이지를 가리킴
    • 예시 속성에는 url, isPartOf, name, inLanguage, breadcrumb가 포함됨
    • ProfilePage, CollectionPageWebPage의 더 구체적인 하위 타입임
    • 덜 일반적인 하위 타입은 Schema.org의 WebPage 정의에서 확인할 수 있음

개인 식별과 프로필 페이지

  • Person

    • 개인 웹사이트의 모든 페이지에는 Person 노드를 넣는 것이 권장됨
    • Person은 사이트 주인이 누구인지 나타내며, Google의 콘텐츠 품질 지표 일부로 사용됨
    • LLM 크롤러도 답변에서 누구를 인용할지 판단할 때 Person 정보를 점점 더 사용함
    • WebSite와 달리 Person은 모든 페이지에 포함할 만큼 중요한 맥락임
    • 중요한 속성은 다음과 같음
      • url: 루트 페이지를 가리켜 노드를 고정함
      • name, givenName, familyName: 이름을 명확히 나타냄
      • image: 가능하면 본인 사진이나 관련 로고를 사용해 정식 이미지를 연결함
      • sameAs: 다른 프로필을 크롤러에 알려 인물 식별에 도움을 줌
    • sameAs는 특히 흔한 이름을 가진 경우 동명이인 구분에 유용하며, 여러 페이지에 걸친 지식 그래프 표현을 만드는 데 쓰임
    • 다른 Person 속성은 세부 정보를 더하는 데 유용하지만 필수는 아니며, 줄여도 영향은 작음
  • ProfilePage

    • ProfilePage는 사이트 안에서 특정 인물에 관한 페이지를 나타냄
    • 홈 페이지에서 자신을 소개한다면 홈 페이지에 쓸 수 있고, 별도 about 페이지가 있다면 그곳에 두는 것이 더 적절할 수 있음
    • isPartOf로 더 넓은 WebSite 노드와 연결하는 것이 중요함
    • mainEntity는 해당 페이지가 누구에 관한 것인지 크롤러에 알려줌
    • dateCreated, dateModified는 크롤러에 대한 최신성 신호로 유용하지만, 사이트에서 쉽게 제공되지 않는다면 크게 걱정할 필요는 없음

프로젝트와 경로 표시

  • SoftwareApplication

    • 페이지에서 소프트웨어를 소개한다면 SoftwareApplication 노드로 해당 소프트웨어의 메타데이터를 담는 것이 좋음
    • 더 구체적인 타입으로는 MobileApplication, WebApplication, VideoGame을 사용할 수 있음
    • url 속성은 프로젝트가 배포된 위치를 가리켜야 함
    • 예시로 crates.io 같은 배포 페이지가 해당됨
    • sameAs는 소스 코드 저장소처럼 프로젝트와 연결된 다른 페이지에 사용함
    • applicationCategory의 유효한 값은 Google의 SoftwareApplication 정의에서 확인할 수 있음
    • FOSS 프로젝트라도 offers를 포함하고 가격을 0으로 설정해야 함
  • BreadcrumbList

    • BreadcrumbList는 루트 페이지를 제외한 모든 페이지에 널리 유용함
    • 페이지의 분류 경로를 나타내며, 실제 URL 경로와 반드시 같을 필요는 없음
    • 검색 엔진이 특정 페이지의 경로를 어떻게 표시할지 제어하는 데 사용할 수 있음
    • 사이트 경로가 이미 짧다면 이 노드의 이득은 작아 생략할 수 있음
    • 경로가 긴 사이트에서는 BreadcrumbList가 검색 결과의 경로를 짧게 만드는 데 유용함

목록, 블로그, 글 페이지

  • CollectionPage

    • CollectionPage는 주로 목록을 담는 페이지에 쓰는 WebPage의 하위 타입임
    • 다른 프로필을 모아둔 /elsewhere/ 페이지나 블로그 글 목록인 /blog/ 페이지가 예시임
    • about으로 관련 Person 노드를 연결할 수 있음
    • breadcrumb는 반드시 현재 페이지의 올바른 BreadcrumbList와 연결해야 함
  • Blog

    • Blog 노드는 블로그의 인덱스나 홈 페이지에 추가함
    • WebSite와 개별 BlogPosting 사이를 잇는 중간 노드 역할을 함
    • dateModified는 최신성 신호로 유용하지만, 쉽게 제공할 수 없다면 생략해도 됨
    • license는 크롤러가 글을 어떤 조건에서 사용할 수 있는지 알게 함
    • 개인 웹사이트에서는 publisherOrganization이 아니라 Person으로 설정해도 됨
    • Google 문서는 이전과 달리 Person도 유효하게 허용하며, 개인 웹사이트에는 더 정확할 수 있음
  • BlogPosting

    • BlogPosting은 게시된 모든 블로그 글에 포함해야 함
    • 크롤러가 글을 더 정확하게 표현할 수 있도록 추가 정보를 제공함
    • 검색 결과에서 더 정확한 위치 배치와 풍부한 세부 정보를 제공하는 데 쓰일 수 있음
    • 개인 사이트에서는 authorpublisher가 같은 Person 노드를 가리켜도 괜찮음
    • image 속성은 글의 링크 미리보기에 이미 쓰는 OG 이미지와 맞추는 것이 좋음
    • license는 글의 이용 조건을 나타내는 데 사용할 수 있음

최소 구현과 적용 기준

  • 개인 사이트에 필요한 JSON-LD는 페이지 성격에 따라 선택적으로 구성할 수 있음
  • 빌드 단계가 없는 정적 사이트라도 루트 페이지에 최소한 다음 노드를 추가해 이점을 얻을 수 있음
    • WebSite
    • ProfilePage
    • Person
  • 블로그가 있다면 BlogBlogPosting을 추가하고, 글 목록이나 외부 프로필 목록 페이지에는 CollectionPage를 사용할 수 있음
  • 프로젝트 소개 페이지에는 SoftwareApplication, 루트가 아닌 페이지에는 BreadcrumbList를 검토할 수 있음

댓글과 토론

Hacker News 의견들
  • 비유를 빌리면 지난 전쟁을 다시 싸우는 느낌임
    내 WWW 사이트 입장에서는 Google이 이제 내 실제 글로 사람들을 보내기보다, 오류가 섞인 긴 LLM 생성 요약을 위에 보여줌
    ‘브레드크럼’이나 도메인 대신 예쁜 표시 이름을 얻는 건, Google이 그런 요소들을 예쁘게 다듬든 말든 우선순위를 낮춘다는 현실을 해결하지 못함
    실제 사이트에 직접 오는 사람은 절대 보지 못하고, Google을 쓰는 사람은 Google 자체의 LLM화된 버전 아래로 밀려 찾기 어려운 것에 너무 많은 노력을 들이는 셈임

    • 이런 데이터가 의미 있는 세상을 원한다면, 먼저 씨를 뿌려야 함
      Google이 쓰지 않더라도 인터넷 전체가 이런 메타데이터를 적용하면, LLM 스크래핑이 아닌 경쟁자들이 대안을 제공하기 좋은 토양이 됨
      Google에 굴복하면 지배력만 강화되고, 경쟁자의 진입 장벽이 높아지며, 그들도 같은 기술을 쓰도록 몰리게 됨
    • 정말 그렇다. 우리 회사도 이제 Google 검색에서 이렇게 나옴:
      $STATE 기반 IT 회사로, 중서부 기업을 위한 실용적 AI 워크플로와 정보 관리 솔루션 구축을 전문으로 한다. 민첩한 고정가 계약 모델로 운영되며, 엔터프라이즈식 비대화를 피하면서 구체적 결과를 제공하는 데 집중한다
      우리가 이제 실용적 AI 워크플로를 제공하는 줄은 몰랐음
      그러고는 비슷하지만 분명히 다른 이름의 경쟁사 이름을 섞고, 나를 임원으로 올려둠. 그나마 다행인 건 경쟁사는 연락처를 “상담 예약” 양식 뒤에 숨겨놔서 우리 연락처만 표시된다는 점임
    • 이제는 Google이 내 사이트를 크롤링하고 색인화하는 것도 허용하지 않음
    • 이제 Google도 “봇이 사이트에 들어오면 10GB zipbomb을 받는” 대상에 포함했음
      지금은 아무 가치도 더하지 않고 문제만 더 일으킴
    • 맞음. 몇 년 동안 트래픽을 가져다주길 바라며 웹사이트에 microdata 태그와 속성을 잔뜩 넣었음
      결과적으로는 사람들이 Google을 떠나지 않도록 Google의 AI를 학습시킨 것뿐이었음
  • 실용적인 성향이라면 웹사이트용 Google 문서에서 JSON-LD를 읽어보길 권함
    https://developers.google.com/search/docs/appearance/structu...
    많은 정보가 일부 사이트에만 관련 있다는 점도 보일 것임. Rotten Tomatoes는 JSON-LD로 영화 평론가 평점을 발행할 수 있지만, 내가 영화 리뷰를 쓴다고 해도 나에게는 별로 관련 없음
    JSON-LD는 쉽고 실제로 검색 엔진이 쓰기 때문에 괜찮음. 웹페이지 안의 정보를 중복할 수는 있지만, 정보가 문서에 정확히 한 번만 나타나도록 완벽하게 주석 처리한다는 꿈은 구형 소와 질량 없는 밧줄 같은 이상화에 가깝다고 봄
    웹페이지를 만들려면 사람의 노력이 필요하고, 최종 결과물에 약간의 중복이 있는 건 괜찮음

    • 큰 사이트가 아니어도 영화 리뷰에 JSON-LD를 쓸 수 있음
      내 사이트에서는 책, 게임, 영화 리뷰에 쓰고 있는데, 대부분의 검색 엔진에서 별점 같은 정보가 표시되는 듯함
    • 403. That’s an error.
      클라이언트가 이 서버의 /search/docs/appearance/structured-data/intro-structured-data URL을 가져올 권한이 없다고 나옴
    • 하지만 데이터를 중복하면 물 사용량이 늘어날 텐데. /s
  • 풍부한 링크 미리보기에는 JSON-LD보다 OpenGraph가 훨씬 더 자주 지원됨
    검색 엔진 최적화 목적이라면 검색 엔진이 지원하는 JSON-LD 종류는 매우 구체적이고 제한적임. 대상 검색 엔진 문서, 즉 Google[1]이나 Bing[2]을 보고 그대로 따르는 편이 훨씬 낫고, 그 외는 시간 낭비에 가까움
    검색 엔진 밖에서도 특정 목적이 없다면 JSON-LD는 대체로 쓸모가 없음. JSON-LD가 필요한 구체적인 요구가 있다면 유용할 데이터를 넣으면 되지만, 그 밖의 데이터를 넣는 건 허공에 외치는 것과 비슷함
    IndieWeb[3]는 구조화 데이터를 쓰지만 JSON-LD를 DRY 위반으로 보고 대신 Microformats[4]를 사용함
    0: https://ogp.me
    1: https://developers.google.com/search/docs/appearance/structu...
    2: https://www.bing.com/webmasters/help/marking-up-your-site-wi...
    3: https://indieweb.org/
    4: https://microformats.org/

  • 모든 웹사이트에 실제로 구현하고 싶은 것은 Schema.org 어휘를 쓰는 구조화 데이터임
    JSON-LD는 그 방법 중 하나이고, RDFa와 Microdata도 있음
    처음 배울 때 이 글을 참고했고 추천할 만함: https://neilpatel.com/blog/get-started-using-schema/
    어떤 데이터를 추가할지 이 도구로 살펴볼 수 있음: https://technicalseo.com/tools/schema-markup-generator/
    전체 목록은 schema.org 사이트에서 볼 수 있음: https://schema.org/docs/schemas.html

  • 몇 년 전에 비행기표가 삽입되거나 배송 추적 정보가 보이는 화려한 이메일 기능이 전부 이메일 안의 JSON-LD로 구현된다는 걸 알게 됨
    다만 내가 알기로는 Gmail만 지원함
    추가 정보: https://www.emailonacid.com/blog/article/email-development/s...

    • Outlook과 iCloud도 티켓이나 예약 같은 일부 기능은 지원함
  • 이런 속성들이 실제로 검색 노출에 도움이 되는 건지, 아니면 검색 엔진이 사용자를 검색 결과 페이지에 붙잡아두기 쉽게 만드는 건지 궁금함

    • JSON-LD를 추가했더니 Google이 내 사이트 안으로 들어가는 하위 링크를 보여주기 시작했음. 그건 괜찮았음
    • 비즈니스 사이트라면 JSON-LD가 지도 플랫폼에 데이터를 공급하는 데 쓰일 수 있음
      주소, 영업시간, 전화번호, 메뉴 같은 것들임
  • 이미 시맨틱 HTML이 있는데, 이상하게도 브라우저가 처리하지 않는 script 태그 안의 맞춤형 이상한 JSON으로 웹사이트의 의미를 또다시 표현해야 함

    • 내 웹사이트에서 JSON-LD를 써봤는데, 시맨틱 HTML과는 별도의 필요를 채워준다고 봄
      시맨틱 HTML은 제목과 헤딩처럼 브라우저가 처리하는 것을 지정함. JSON-LD 데이터는 생성일, 수정일, 태그, 저자 같은 메타데이터
      이런 것들은 HTML 안에서 microdata로도 표현할 수 있지만, JSON-LD가 더 쉬워서 microdata 사용을 중단했음
      JSON-LD는 사이트를 생성하는 데 쓰는 동일한 데이터에서 채우고, 이 메타데이터로 2024년 블로그 글 목록이나 주제 X 관련 글 전체 같은 색인 페이지도 만듦. JSON-LD의 주된 소비자는 검색 엔진임
      더 열받고 싶다면 같은 페이지에 OpenGraph 메타데이터도 넣고 있다는 걸 생각해보면 됨. 같은 페이지에 서로 다른 메타데이터 형식이 두 개 있는 셈임
    • Microdata도 있고, 내가 틀리지 않았다면 JSON-LD와 같은 어휘를 지원함. schema.org가 좋은 자료임
      다만 JSON-LD가 한동안 기본값이 되어왔고, 우리가 REST를 대체로 버리고 RPC로 간 것과 비슷함. 지금도 중요한 파서들이 microdata를 모두 지원하는지는 잘 모르겠고, 특히 Google 검색 노출을 원하는 전자상거래 사이트 같은 클라이언트 사이트를 만들 때는 기본적으로 LD를 써왔음
      시맨틱 HTML과 비교할 때도 주목할 점이 있음. 시맨틱 HTML은 마크업 구조를 정의하는 데 도움을 주지만, “이것은 판매 중인 제품”이나 “이것은 열차 시간표” 같은 현실 세계의 맥락까지 표현하지는 못함
    • 글을 충분히 이해하지 못한 것 같음
      JSON-LD와 script 태그 없이도 HTML 안에서 Schema.org/FOAF/WikiData 같은 온톨로지를 쓸 수 있음
    • 이상적인 세상은 서버와 브라우저가 콘텐츠 협상을 할 수 있고, 브라우저가 먼저 웹사이트에서 JSON-LD만 요청한 뒤 자체 내부 렌더러 형식을 사용하는 것이라고 봄
    • 시맨틱 HTML은 JSON-LD와 다른 마이크로포맷이 다루는 범위를 포괄하지 않음
      글에 나온 것만 봐도 사람, 브레드크럼 목록, 소프트웨어 애플리케이션, 블로그, 블로그 게시글을 나타내는 시맨틱 요소가 무엇인지 묻게 됨
      시맨틱 HTML은 스크린 리더를 쓰는 사람이 “내비게이션”이나 “기사” 같은 일반 요소를 탐색하도록 돕기 위한 것임
  • 이건 그냥 OpenGraph를 JSON으로 쓴 것 아닌가? 장점이 뭐임?

  • 2024년 이후 우리 콘텐츠 기반 마케팅 페이지 트래픽이 약 85% 줄었음
    이해가 안 되는 건, 제로 클릭 검색 결과 페이지가 늘었는데 Google도 크게 타격을 받지 않았느냐는 점임
    클릭 기반인 검색 결과 페이지 광고 매출도 비슷하게 심각하게 줄었어야 할 텐데, 이 가설을 반박하거나 확인할 공개 수치를 찾지 못했음

  • 어느 선을 넘으면 공생이 착취로 바뀌는 미묘한 균형이 있음
    웹사이트가 검색 엔진의 도움으로 노출을 얻으려는 관계는 상당 부분 상호 이익이었음
    하지만 지금은 웹사이트 소유자가 땀 흘려 만든 작업에서 아무것도 얻지 못하는 방향으로 완전히 가고 있음