워드프레스에 JSON-LD를 넣으려고 검색하다 보면 플러그인 설정 화면 캡처만 잔뜩 나오고, 정작 “자동 발행 파이프라인에서 매번 자동으로 넣으려면 어떻게 하냐”는 질문엔 속 시원한 답을 찾기 어렵습니다. 결론부터 말하면, REST API 하나만으로는 절대 불가능하고 반드시 서버 쪽에 최소한의 PHP 코드가 한 번은 심어져 있어야 합니다. 이 글에서는 그 이유와 실제 동작하는 코드까지 정리합니다.
JSON-LD가 정확히 무엇인가
JSON-LD(JSON for Linking Data)는 웹페이지에 구조화된 데이터를 삽입하는 형식입니다. 검색엔진이 페이지 내용을 사람처럼 추측하지 않고, “이건 기사이고 작성자는 누구이며 발행일은 언제다” 같은 정보를 기계적으로 정확히 읽게 해주는 역할을 합니다.
가장 큰 특징은 화면에 보이는 콘텐츠와 완전히 분리된 <script> 태그 안에 들어간다는 점입니다. 본문 HTML 구조를 건드리지 않고 메타데이터만 별도로 추가할 수 있어서, 마이크로데이터(Microdata)나 RDFa 같은 다른 방식보다 관리가 훨씬 쉽습니다. 구글도 공식적으로 JSON-LD를 권장 방식으로 안내하고 있으며, RankMath나 Yoast 같은 주요 SEO 플러그인도 전부 이 형식으로 출력합니다.
기본 구조는 다음과 같습니다.
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Article",
"headline": "글 제목",
"datePublished": "2026-09-04"
}
</script>
@context는 어떤 어휘 체계를 쓰는지, @type은 데이터 종류(Article, FAQPage, Product 등)를 나타냅니다. 이 구조를 검색엔진이 읽어서 검색결과에 별점, FAQ 아코디언, 가격 정보 같은 리치 스니펫을 노출시켜주는 것입니다.
왜 JSON-LD를 신경 써야 하는가
단순히 “구글이 권장해서”가 아니라 실질적인 트래픽 효과가 있기 때문입니다. 리치 스니펫이 노출되면 검색결과 화면에서 눈에 띄어 클릭률이 올라갑니다. FAQPage 스키마를 넣으면 질문과 답변이 검색결과에 아코디언 형태로 바로 노출되기도 합니다. 최근에는 AI 기반 검색 요약 기능도 페이지의 구조화 데이터를 참고 자료로 활용하는 경향이 있어, 앞으로 중요도는 더 커질 가능성이 높습니다.
블로그 운영 관점에서 자주 쓰이는 타입은 다음과 같습니다.
- Article / BlogPosting: 제목, 저자, 발행일 등 기본 글 정보
- FAQPage: 글 하단 FAQ를 검색결과에 아코디언으로 노출
- BreadcrumbList: 사이트 내 탐색 경로 표시
- HowTo: 단계별 튜토리얼 콘텐츠
RankMath에서 커스텀 JSON-LD를 넣는 두 가지 축
자동 발행 파이프라인을 운영한다면 매번 관리자 화면에서 수동으로 스키마를 채워 넣을 수 없습니다. 이럴 때 필요한 게 두 가지 축입니다.
첫 번째 축은 렌더링입니다. rank_math/json_ld라는 필터를 이용하면, RankMath가 만든 스키마 배열에 끼어들어 커스텀 데이터를 추가하거나 수정할 수 있습니다.
add_filter( 'rank_math/json_ld', function( $data, $jsonld ) {
if ( is_singular( 'post' ) ) {
$data['CustomSchema'] = [
'@type' => 'FAQPage',
'mainEntity' => [ /* ... */ ],
];
}
return $data;
}, 99, 2 );
두 번째 축은 데이터 전달입니다. 자동 발행 스크립트가 글을 생성할 때 REST API를 통해 이 스키마 내용을 post meta로 함께 실어 보내는 방식입니다.
두 축은 서로 대체 관계가 아니라 보완 관계입니다. 필터만 있으면 어디서 데이터를 가져올지가 없고, REST API로 데이터만 밀어넣으면 그걸 실제로 출력해주는 로직이 없습니다.
REST API만으로는 왜 안 되는가
여기서 많은 사람이 헷갈리는 지점이 있습니다. “REST API로 meta 필드를 보내기만 하면 자동으로 화면에 나오지 않나?”라는 생각인데, 실제로는 그렇지 않습니다.
워드프레스 REST API는 기본적으로 등록되지 않은 meta key는 조용히 무시합니다. 요청을 보내면 200 OK 응답이 오지만 실제로는 아무것도 저장되지 않는 경우가 흔합니다. RankMath의 SEO 제목이나 메타 설명 같은 필드조차 기본 설정으로는 REST API에 노출되어 있지 않아서, 이를 위한 별도 연동 작업이 필요할 정도입니다.
즉 REST API 단독으로 자동화를 완성하려면 최소 두 단계가 필요합니다.
register_post_meta()로 커스텀 meta key를 REST API에 명시적으로 노출rank_math/json_ld필터로 저장된 meta를 읽어 실제 JSON-LD로 출력
다행히 이 두 단계는 한 번만 세팅해두면 이후로는 발행 자동화 쪽에서 REST API 호출만으로 계속 재사용할 수 있습니다.
실제 동작 코드
functions.php(또는 Code Snippets 플러그인)에 아래 코드를 추가합니다.
// 1. custom_json_ld meta key를 REST API에 노출
add_action( 'init', function() {
register_post_meta( 'post', 'custom_json_ld', [
'type' => 'string',
'single' => true,
'show_in_rest' => true,
'sanitize_callback' => function( $value ) {
json_decode( $value );
return json_last_error() === JSON_ERROR_NONE ? $value : '';
},
'auth_callback' => function() {
return current_user_can( 'edit_posts' );
},
] );
} );
// 2. 저장된 meta를 RankMath 출력에 병합
add_filter( 'rank_math/json_ld', function( $data, $jsonld ) {
if ( ! is_singular( 'post' ) ) {
return $data;
}
$raw = get_post_meta( get_the_ID(), 'custom_json_ld', true );
if ( empty( $raw ) ) {
return $data;
}
$custom = json_decode( $raw, true );
if ( json_last_error() !== JSON_ERROR_NONE || ! is_array( $custom ) ) {
return $data;
}
$key = isset( $custom['@type'] ) ? $custom['@type'] . '_custom' : 'CustomSchema';
$data[ $key ] = $custom;
return $data;
}, 99, 2 );
이후 발행 자동화 스크립트에서는 글을 생성할 때 아래처럼 meta.custom_json_ld 필드에 JSON 문자열을 담아 보내기만 하면 됩니다.
curl -X POST "https://예시사이트.com/wp-json/wp/v2/posts" \
--user "계정:애플리케이션_비밀번호" \
-H "Content-Type: application/json" \
-d '{
"title": "글 제목",
"content": "...",
"status": "publish",
"meta": {
"custom_json_ld": "{\"@context\":\"https://schema.org\",\"@type\":\"FAQPage\",\"mainEntity\":[]}"
}
}'
적용 시 주의할 점
몇 가지 실수하기 쉬운 부분을 짚고 넘어가겠습니다. custom_json_ld 값은 JSON 문자열을 이스케이프해서 넣어야 하며, 이중 인코딩이 되지 않도록 스크립트 쪽에서 JSON.stringify() 결과를 한 번만 문자열화해야 합니다. 또한 is_singular('post') 조건은 페이지나 커스텀 포스트 타입까지 확장할 수 있으니 운영 중인 사이트 구조에 맞게 조정하는 것이 좋습니다.
배포 후에는 반드시 구글의 리치 결과 테스트 도구로 실제 출력된 JSON-LD가 유효한지 확인하는 절차를 거치는 것을 권장합니다. 스키마 문법 오류는 검색엔진이 그냥 무시하고 넘어가기 때문에, 별도로 검증하지 않으면 몇 달이 지나도 문제를 알아채지 못할 수 있습니다.
자주 묻는 질문
Q. RankMath 없이 순수 워드프레스만으로도 JSON-LD를 넣을 수 있나요?
가능합니다. wp_head 훅에 직접 <script> 태그를 출력하면 되지만, 이 경우 RankMath가 자동 생성하는 기본 스키마와 중복되지 않도록 별도로 관리해야 합니다.
Q. 필터 우선순위(99)는 왜 이렇게 높게 설정하나요?
RankMath 자체 로직이 먼저 스키마 배열을 다 채운 뒤에 커스텀 데이터를 병합해야 값이 덮어써지지 않기 때문입니다. 숫자가 클수록 나중에 실행됩니다.
Q. 커스텀 post type에도 적용할 수 있나요?
register_post_meta()의 첫 번째 인자와 is_singular() 조건의 post type 이름만 바꿔주면 동일하게 적용됩니다.
마무리
워드프레스에서 JSON-LD를 자동 발행 파이프라인에 연결하려면 REST API 하나만으로는 부족하고, meta key 등록과 출력 필터라는 최소한의 서버 사이드 코드가 한 번은 필요합니다. 다만 이 세팅은 딱 한 번만 해두면 이후에는 발행 스크립트에서 REST API 호출만으로 완전히 자동화할 수 있다는 점이 핵심입니다. 구조화 데이터는 당장 눈에 보이는 효과가 크지 않아 보여도, 검색엔진이 콘텐츠를 이해하는 방식에 직접 영향을 주는 만큼 발행 파이프라인 초기 단계에 함께 설계해두는 것을 권장합니다.