블로그 구조화 데이터 JSON-LD 처음 삽입부터 Rich Results Test 오류 수정까지

워드프레스 기본 테마에 SEO 플러그인을 쓰지 않는 환경이라면, 블로그 구조화 데이터 JSON-LD를 직접 손으로 넣어야 한다. 이 글은 코드를 처음 만드는 단계부터 functions.php에 넣고 Rich Results Test에서 녹색 체크가 뜰 때까지 실제 흐름을 따라간다.
시작 전에 플러그인이 이미 있는지 확인한다
직접 코드를 넣기 전에 먼저 확인해야 할 게 있다. Yoast나 Rank Math 같은 SEO 플러그인이 설치되어 있다면 Article 스키마를 자동으로 출력하고 있을 가능성이 크다. 플러그인 스키마가 돌아가는 상태에서 직접 코드까지 추가하면 같은 타입이 두 번 출력되는 중복 구조화 데이터 상태가 된다. 두 코드의 값이 엇갈리면 신뢰도가 떨어지므로, Yoast·Rank Math를 쓰고 있다면 이 글 방식 대신 플러그인의 스키마 설정을 활용하는 게 낫다.
코드를 만든다
구글이 공식 권장하는 방식은 JSON-LD다. HTML 본문 구조와 완전히 분리되어 <script type="application/ld+json"> 태그 하나에 데이터만 담기 때문에 나중에 수정할 때 본문을 건드릴 필요가 없다.
타입은 Article부터 시작한다. 일반 블로그 포스트라면 하위 타입인 BlogPosting이 더 정확하지만, 구글 서치 센트럴은 Article도 그대로 인정한다.
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Article",
"headline": "여기에 글 제목을 그대로 쓴다",
"author": {
"@type": "Person",
"name": "저자 이름"
},
"datePublished": "2026-09-21T09:00:00+09:00",
"dateModified": "2026-09-21T09:00:00+09:00",
"image": {
"@type": "ImageObject",
"url": "https://yourdomain.com/images/post-thumbnail.jpg",
"width": 1200,
"height": 630
}
}
</script>
많은 안내 글이 headline, author, datePublished, image를 "필수 필드"라고 쓴다. 구글 서치 센트럴의 Article 구조화 데이터 문서에는 required properties 항목이 없다. 이 네 가지는 권장(recommended) 속성이다. 빠져도 오류가 뜨진 않지만, 없으면 리치 결과에 표시할 정보가 줄어들므로 넣는 게 이득이다.
값을 채울 때 실수가 가장 많이 나오는 지점은 두 군데다.
날짜 형식: datePublished는 ISO 8601 형식이어야 한다. "2026년 9월 21일" 같은 자연어를 그대로 쓰면 Rich Results Test에서 즉시 오류로 잡힌다. 한국 시간이면 +09:00까지 붙여야 한다.
이미지 경로: image의 url은 반드시 절대 경로여야 한다. /images/photo.jpg처럼 상대 경로로 넣으면 유효하지 않다고 나온다. https://부터 시작하는 전체 URL을 써야 하며, 이미지 폭이 1200px 이상이면 구글의 리치 결과 미리보기에서 대형 이미지로 표시된다.
@context와 @type 이 두 줄은 없으면 구조화 데이터 블록 자체가 무효가 되므로 반드시 들어가야 한다.
functions.php에 넣는다
코드를 만들었으면 functions.php에서 wp_head 훅으로 주입한다. 단일 글 페이지에만 적용하려면 is_single() 조건을 붙인다.
function my_article_jsonld() {
if ( is_single() ) {
$post = get_post();
$thumb_id = get_post_thumbnail_id();
$thumb_url = $thumb_id ? wp_get_attachment_image_url( $thumb_id, 'large' ) : '';
$schema = [
'@context' => 'https://schema.org',
'@type' => 'Article',
'headline' => get_the_title(),
'author' => [
'@type' => 'Person',
'name' => get_the_author_meta( 'display_name', $post->post_author ),
],
'datePublished' => get_the_date( 'c', $post ),
'dateModified' => get_the_modified_date( 'c', $post ),
];
if ( $thumb_url ) {
$schema['image'] = [ '@type' => 'ImageObject', 'url' => $thumb_url ];
}
echo '<script type="application/ld+json">'
. wp_json_encode( $schema, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES )
. '</script>' . "\n";
}
}
add_action( 'wp_head', 'my_article_jsonld' );
get_the_title(), get_the_date('c') 같은 워드프레스 함수로 동적으로 채우면 글마다 고유한 값이 자동으로 들어가고, 수정 시 dateModified도 자동 갱신된다. get_the_date('c')의 c는 ISO 8601 형식을 반환하는 PHP 날짜 포맷 문자다. wp_get_attachment_image_url()은 절대 URL을 반환하므로 이미지 경로 오류도 자동으로 피할 수 있다.
Rich Results Test에서 결과를 읽는다
코드를 넣었으면 search.google.com/test/rich-results에서 글 URL을 입력한다. 아직 라이브가 아니라면 코드 직접 붙여넣기 탭을 쓴다.
결과 화면 상태는 세 가지다.
녹색 체크: "Article 항목이 유효합니다". 정상 인식이라는 뜻이다.
경고(Warning): 노란색으로 표시된다. 권장 속성이 빠졌을 때 나온다. 경고가 있어도 리치 결과 자격은 유지된다. 해당 속성이 있을 때 추가로 표시될 수 있는 정보가 제한되는 것이지, 리치 결과 자체를 막지는 않는다.
오류(Error): 빨간색이며 리치 결과 자격이 없어지는 수준의 문제다. @type이나 @context가 빠지면 Missing field, 날짜를 자연어로 쓰거나 이미지를 상대 경로로 넣으면 Invalid value로 잡힌다. 오류 항목을 클릭하면 코드 탐색기로 해당 줄로 바로 이동한다.
오류가 여러 개 떴을 때 수정 순서
@context와 @type 문제를 가장 먼저 잡는다. 이 두 개가 없거나 잘못되면 나머지를 고쳐도 전체 블록이 무효가 된다. 그다음은 Invalid value 유형이다.
날짜는 "2026.09.21" 형태를 "2026-09-21T09:00:00+09:00"으로 바꾸면 바로 해결된다. functions.php 동적 방식을 쓴다면 get_the_date('c')가 ISO 8601을 자동으로 반환하므로 날짜 오류는 거의 발생하지 않는다. 이미지는 상대 경로를 "https://yourdomain.com/images/cover.jpg" 형태의 절대 URL로 바꾼다.
수정 후에는 URL 기반이 아닌 코드 직접 입력 탭으로 다시 확인한다. URL 기반은 캐시 때문에 수정된 코드가 즉시 반영되지 않을 수 있다. 경고는 리치 결과를 막지 않으므로 오류를 먼저 제거하고 녹색 체크가 뜨는 것을 확인하는 게 첫 번째 목표다.
구조화 데이터가 리치 결과를 보장하지는 않는다. 구글이 콘텐츠와 구조화 데이터의 일치 여부, 품질 기준을 별도로 판단하기 때문이다. 그래도 functions.php에 한 번 심어두면 이후 글에서는 추가 작업 없이 자격을 열어두는 셈이니, 안 하는 것보다는 분명히 낫다.
이 글이 도움이 됐나요?
여러분의 반응이 다음 글의 방향이 돼요


