본문 바로가기
Frontend2026년 10월 10일15분 읽기

서치 콘솔 itemReviewed 누락 오류의 정체 — 마이크로데이터와 JSON-LD가 겹친 이름 없는 항목

YS
김영삼
조회 47
서치 콘솔 itemReviewed 누락 오류의 정체 — 마이크로데이터와 JSON-LD가 겹친 이름 없는 항목

서치 콘솔의 "'itemReviewed' 입력란이 누락되었습니다" 오류는, 평가 대상(부모 아이템)과 연결되지 않은 AggregateRating이 페이지 어딘가에 단독으로 있을 때 생긴다. 내 경우 범인은 화면 별점에 붙어 있던 마이크로데이터였고, 같은 평점은 이미 JSON-LD에 제대로 들어 있었다.

즉 구글은 같은 평점을 두 번 신고받은 셈이었다. 한 번은 JSON-LD 안에서 소프트웨어의 평점으로, 또 한 번은 HTML 속에서 주인 없는 평점으로. 두 번째가 "이름 없는 항목"이 되어 오류로 잡혔다. 고친 방법은 의외로 단순해서 화면 별점의 마이크로데이터 속성만 지웠다. 어떻게 찾았고 어떻게 확인했는지 순서대로 적는다.

3줄 요약
  • "이름 없는 항목"의 AggregateRating은 부모 아이템 없이 단독으로 붙은 마이크로데이터인 경우가 많다.
  • JSON-LD에 이미 aggregateRating이 있다면 화면 별점의 itemScope·itemProp은 중복이다. 속성만 지우면 모양은 그대로다.
  • 구조화 데이터는 JSON-LD 한 가지 방식으로, 한 곳에서만 만든다. 화면 값과 JSON-LD 값은 같은 함수에서 나오게 한다.

PART 01서치 콘솔에 뜬 화면

구글 서치 콘솔에서 BoltPDF 프로그램 페이지(youngsam.net/programs/boltpdf)를 URL 검사했더니 개선사항 쪽에 "리뷰 스니펫: 항목 3개 감지됨, 일부 항목이 잘못됨"이 떠 있었다. 펼쳐 보니 감지된 항목은 이랬다.

URL 검사에서 본 리뷰 스니펫 항목 (세 번째의 상세: ratingValue 5.0, bestRating 5, ratingCount 1, itemReviewed 누락)
감지된 항목유형상태정체
BoltPDF리뷰 스니펫유효JSON-LD의 SoftwareApplication (aggregateRating 포함)
BoltPDF리뷰 스니펫유효JSON-LD 쪽에서 나온 BoltPDF 항목
이름 없는 항목AggregateRating중요한 문제화면 별점에 단독으로 붙은 마이크로데이터

세 번째 항목의 상세에는 ratingValue 5.0, bestRating 5, ratingCount 1이 들어 있었고, 그 아래 빨간 글씨로 "'itemReviewed' 입력란이 누락되었습니다"가 중요한 문제로 찍혀 있었다. 처음 보면 꽤 겁이 나는 화면이다. 평점 데이터가 망가졌나, 리뷰 시스템에 문제가 있나 싶다. 그런데 이름 없는 항목의 숫자를 보니 페이지 상단 별점 표시 "★ 5.0 (1)"과 똑같았다. 바로 거기서 실마리가 잡혔다.

그리고 이건 BoltPDF만의 문제가 아니었다. 별점 컴포넌트는 모든 프로그램 페이지가 공유하니, 별점이 있는 프로그램 페이지 전부에서 같은 오류가 나고 있던 것이었다.

삽질 기록 · 화면 별점 하나가 구글에게는 독립된 물건이었다
프로그램 페이지 상단 제목 옆에 별점을 "★ 5.0 (1)" 같은 모양으로 보여 주는 작은 컴포넌트가 있다. 코드를 열어 보니 이 요소에 itemScope itemType="https://schema.org/AggregateRating"이 붙어 있고, 안쪽 숫자들에 itemProp="ratingValue", bestRating, ratingCount가 하나씩 달려 있었다. 아마 "별점이니까 schema 속성을 달아 두면 좋겠지" 하는 마음으로 붙였을 것이다. 문제는 이 요소를 감싸는 부모가 없었다는 점이다. 바깥에 itemScope itemType="SoftwareApplication" 같은 아이템이 없으니, 구글 입장에서 이건 "무엇에 대한 평점인지 모르는 평점" 하나가 페이지에 떠 있는 것이다. 평가 대상이 없으니 itemReviewed가 누락됐다는 오류가 정확한 진단이었다. 한편 같은 평점은 이미 페이지의 JSON-LD 안에 SoftwareApplication.aggregateRating으로 제대로 들어가 있었다. 결국 오류의 정체는 중복 신고였다.

PART 02왜 "이름 없는 항목"이 되는가

마이크로데이터는 HTML 요소에 속성을 붙여 구조를 표현한다. itemScope가 붙은 요소는 하나의 아이템이 되고, 그 안의 itemProp은 가장 가까운 바깥 아이템의 속성이 된다. 그런데 itemScope가 붙은 요소가 다른 아이템의 itemProp이 아니라면, 그건 페이지의 최상위 아이템으로 따로 해석된다.

AggregateRating은 혼자서는 의미가 없는 타입이다. 구글의 리뷰 스니펫 가이드도 평점은 평가 대상 아이템 안에 중첩되거나, itemReviewed로 대상을 가리켜야 한다고 설명한다. 최상위에 홀로 떠 있는 AggregateRating에는 이름(name)도 없고 대상도 없으니 서치 콘솔은 "이름 없는 항목"이라고 표시하고, 필수 입력란인 itemReviewed가 빠졌다고 알려 준다.

화면 별점 컴포넌트 — 수정 전후
// 전: 부모 아이템 없이 단독으로 붙은 마이크로데이터
<span className="rating"
      itemScope itemType="https://schema.org/AggregateRating">
  ★ <span itemProp="ratingValue">{avg.toFixed(1)}</span>
  <meta itemProp="bestRating" content="5" />
  (<span itemProp="ratingCount">{count}</span>)
</span>

// 후: 보이는 모양은 그대로, 의미 속성만 제거
<span className="rating">
  ★ <span>{avg.toFixed(1)}</span>
  ({count})
</span>

수정은 이게 전부다. itemScope, itemType, itemProp, 그리고 meta 태그를 지웠고 클래스와 글자는 건드리지 않았다. 사용자가 보는 별점은 1픽셀도 안 바뀌었다. 같은 컴포넌트가 한국어 페이지와 다국어(en/ja/zh) 페이지에 따로 있어서 두 군데 모두 고쳤다. 한쪽만 고치면 서치 콘솔에서 언어별 URL로 같은 오류가 계속 나올 테니까.

영삼
내 생각
장식용 마크업에 의미(시맨틱) 속성을 섞지 말자는 게 이번 일로 굳힌 생각이다. 화면 별점은 디자인 요소다. 거기에 schema 속성을 달면 디자인을 바꿀 때마다 구조화 데이터가 같이 흔들리고, 반대로 구조화 데이터를 고칠 때 디자인 코드를 뒤져야 한다. 보여 주는 코드와 기계에게 설명하는 코드는 따로 두는 게 맞다.

PART 03마이크로데이터 vs JSON-LD

둘 다 구글이 읽는 형식이다. 기능만 보면 같은 걸 표현할 수 있다. 하지만 유지보수 관점에서는 차이가 크고, 구글도 문서에서 JSON-LD를 권장한다고 밝히고 있다.

두 방식을 섞으면 내 경우처럼 같은 정보를 두 번 신고하게 된다
구분마이크로데이터JSON-LD
위치HTML 요소 속성(itemScope, itemProp)으로 본문에 흩어짐<script type="application/ld+json"> 한 덩어리
구조 표현DOM 중첩이 곧 데이터 중첩 — 부모를 빠뜨리면 고아가 됨객체 중첩을 명시적으로 씀
디자인과의 관계디자인 변경이 데이터를 깨뜨릴 수 있음화면 마크업과 독립
중복 위험컴포넌트마다 붙이다 보면 같은 정보가 여러 번 나옴한 곳에서 생성하면 중복을 통제하기 쉬움
검토 난이도여러 컴포넌트를 다 열어 봐야 전체가 보임페이지 소스 한 곳만 보면 됨
구글 권장지원함권장 형식으로 안내됨

내 사이트는 원래 JSON-LD를 주력으로 쓰고 있었다. 프로그램 페이지마다 SoftwareApplication 객체를 만들고 그 안에 aggregateRating을 넣는다. 그런데 컴포넌트 한 구석에 마이크로데이터가 남아 있었고, 두 방식이 서로를 모른 채 같은 평점을 각자 신고하고 있었다. 섞어 쓰는 게 금지는 아니지만, 섞는 순간 "이 정보가 몇 번, 어디서 나가는가"를 사람이 추적해야 한다.

PART 04올바른 JSON-LD는 이렇게 생겼다

aggregateRating은 평가 대상 객체 안에 넣는다. 이렇게 중첩하면 itemReviewed를 따로 쓸 필요가 없다. 부모가 곧 평가 대상이기 때문이다. SoftwareApplication은 구글 문서에서 aggregateRating이나 review를 지원하는 타입으로 안내되어 있다.

SoftwareApplication 안에 aggregateRating을 중첩한 예
{
  "@context": "https://schema.org",
  "@type": "SoftwareApplication",
  "name": "BoltPDF",
  "applicationCategory": "BusinessApplication",
  "operatingSystem": "Windows",
  "offers": { "@type": "Offer", "price": "0", "priceCurrency": "KRW" },
  "aggregateRating": {
    "@type": "AggregateRating",
    "ratingValue": "5.0",
    "bestRating": "5",
    "ratingCount": "2"
  }
}

여기서 내가 신경 쓰는 건 숫자의 출처다. 화면 별점, 리뷰 목록 헤더, JSON-LD에 들어가는 평점이 서로 다르면 구글이 "보이는 내용과 구조화 데이터가 다르다"고 판단할 여지가 생긴다. 그래서 youngsam.net에서는 평점 평균과 개수를 공통 함수 하나로 계산하고, 화면 표시·리뷰 헤더·JSON-LD가 모두 그 결과를 쓴다.

자기 회사 리뷰는 별도로 조심. 구글은 LocalBusiness나 Organization 같은 타입에서, 사이트가 자기 자신에 대한 리뷰를 직접 표시하는 경우 리뷰 리치 결과를 제한하는 정책을 두고 있는 것으로 알려져 있다. 소프트웨어나 제품처럼 "사이트가 다루는 대상"에 대한 평점과는 다르게 취급되니, 회사 소개 페이지에 별점을 달 생각이라면 최신 가이드를 먼저 확인하는 게 좋다.

PART 05배포 후 검증 흐름

고쳤다고 끝이 아니다. 실제로 오류가 사라졌는지, 그리고 정상 데이터까지 같이 지워 버리지 않았는지 둘 다 확인해야 한다. 내가 한 확인에 리치 결과 테스트를 더한 순서는 이렇다.

1
배포 후 페이지 소스를 직접 확인
HTML에서 schema.org/AggregateRating 마이크로데이터가 0개인지 본다. 동시에 JSON-LD 안의 aggregateRating이 그대로 남아 있는지 확인한다. (구글이 크롤링했을 때는 리뷰가 1건이었고, 고칠 즈음엔 새 리뷰가 승인돼 2건이었다. 숫자가 화면·JSON-LD에서 함께 바뀌면 정상이다.) 지워야 할 것과 남겨야 할 것을 둘 다 본다.
2
리치 결과 테스트로 한 번 더
구글 리치 결과 테스트에 URL을 넣어 감지 항목에서 "이름 없는 항목"이 사라졌는지 본다. 서치 콘솔보다 결과가 빨리 나와서 배포 직후 확인용으로 좋다.
3
서치 콘솔 URL 검사 → 실제 URL 테스트
색인된 버전이 아니라 지금 서버가 내보내는 버전을 구글이 다시 읽게 한다. 리뷰 스니펫 항목이 오류 없이 나오는지 확인한다.
4
개선사항 → 리뷰 스니펫 → 수정 결과 확인
해당 오류 항목에서 수정 결과 확인을 눌러 검증을 시작한다. 같은 오류가 나던 다른 프로그램 페이지들도 구글이 차례로 다시 확인한다. 이 단계는 시간이 걸리니 기다린다.
5
다국어 페이지도 샘플 확인
en/ja/zh 페이지 하나씩을 골라 같은 방식으로 확인한다. 컴포넌트가 따로였으니 결과도 따로 확인해야 마음이 놓인다.

첫 단계에서 "남겨야 할 것"을 같이 확인하는 게 중요하다. 오류를 없애려고 구조화 데이터를 통째로 지우면 서치 콘솔은 조용해지지만 리치 결과 자격도 같이 사라진다. 오류 0개가 목표가 아니라, 올바른 데이터 1벌이 목표다.

영삼
내 생각
서치 콘솔 오류는 겁먹을 일이 아니라 "중복 신고"일 때가 많다고 본다. 빨간 글씨는 무섭지만, 내용을 읽어 보면 대개 "같은 걸 두 번 말했는데 한 번은 엉터리로 말했다"는 이야기다. 숫자를 화면과 대조해 보면 어디서 나온 항목인지 금방 보인다. 그리고 리치 결과는 보장이 아니라 자격일 뿐이다. 오류를 다 고쳐도 별점이 검색 결과에 뜰지는 구글이 정한다. 그러니 리치 결과에 집착하기보다 정확한 데이터를 한 벌만 내보내는 데 집중하는 편이 낫다.
itemReviewed 누락 오류를 만났을 때
  1. "이름 없는 항목"의 숫자를 화면과 대조해 어디서 나온 데이터인지 찾는다.
  2. 부모 없이 단독으로 붙은 AggregateRating 마이크로데이터가 있으면 의미 속성만 지운다. 모양은 그대로 둔다.
  3. 구조화 데이터는 JSON-LD로, 한 곳에서만 만든다. 평점은 평가 대상 객체 안에 중첩한다.
  4. 화면·리뷰 헤더·JSON-LD 평점은 공통 함수 하나에서 나오게 한다.
  5. 배포 후 "지운 것 0개, 남긴 것 그대로"를 확인하고 서치 콘솔에서 수정 결과 확인을 요청한다.

자주 묻는 질문

서치 콘솔의 'itemReviewed 입력란이 누락되었습니다' 오류는 무슨 뜻인가요?

평점(AggregateRating)이나 리뷰가 무엇에 대한 것인지 알 수 없다는 뜻이다. 평점이 평가 대상 아이템 안에 중첩되어 있지 않고 itemReviewed로 대상을 가리키지도 않을 때 생긴다. 화면 별점에 단독으로 붙은 마이크로데이터가 흔한 원인이다.

리뷰 스니펫에 '이름 없는 항목'이 감지되는 이유는 무엇인가요?

name 속성이 없는 아이템이 최상위로 해석될 때 그렇게 표시된다. AggregateRating을 itemScope로 단독 선언하면 그 자체가 하나의 아이템이 되는데, 평점에는 보통 이름이 없으니 이름 없는 항목으로 나온다. 부모 아이템과 연결하거나 중복이라면 제거하면 된다.

JSON-LD와 마이크로데이터를 같이 써도 되나요?

구글은 둘 다 읽기 때문에 함께 쓸 수는 있다. 다만 같은 정보를 두 방식으로 내보내면 중복이 생기고, 한쪽 구조가 틀리면 이번 사례처럼 오류가 난다. 구글이 권장하는 JSON-LD 한 가지로 통일하는 편이 관리가 쉽다.

소프트웨어 페이지에 별점 리치 결과를 넣을 수 있나요?

SoftwareApplication은 구글 문서에서 aggregateRating이나 review를 지원하는 타입으로 안내된다. 평점을 SoftwareApplication 객체 안에 중첩하고, 화면에 보이는 평점과 같은 값을 넣으면 된다. 다만 리치 결과 표시 여부는 구글이 결정하므로 자격을 갖추는 것까지가 사이트가 할 수 있는 일이다.

구조화 데이터를 고친 뒤 서치 콘솔에서는 어떻게 확인하나요?

URL 검사에서 실제 URL 테스트로 현재 버전을 다시 읽히고, 개선사항의 해당 리치 결과 보고서에서 수정 결과 확인을 요청한다. 검증에는 시간이 걸린다. 배포 직후에는 리치 결과 테스트로 먼저 확인하면 빠르다.

참고 자료

댓글 0

아직 댓글이 없습니다.
Ctrl+Enter로 등록