블로그 구조화 데이터의 localhost URL 노출 버그 수정
목차
Post.astro 의 Article schema에서 url 필드가 localhost로 박혀있던 문제를 잡았다.
왜 이게 문제였나
구조화 데이터(Structured Data)는 검색엔진이 페이지의 의미를 파악하는 데 쓰인다. 특히 블로그 포스트에 붙이는 Article schema는 url 필드가 있어야 하고, 그 값이 실제 배포 주소여야 한다. 그런데 개발 중에 Astro.url.href 같은 걸 그냥 쓰거나, 혹은 base URL을 별도로 주입하지 않은 채로 두면 로컬 개발 서버 주소(http://localhost:4321/...)가 그대로 빌드 산출물에 박히는 경우가 생긴다.
이게 단순히 "개발 흔적"처럼 보일 수 있는데, 실제 영향이 꽤 있음.
- Google Search Console에서 schema 파싱 오류 또는 경고로 잡힌다
- Rich Result 자격심사에서 url 불일치로 탈락 가능
- 소셜 공유 시 Open Graph랑 혼용되는 메타데이터가 엇갈릴 수 있음
- 외부 aggregator 사이트가 이 schema를 파싱할 때 잘못된 링크를 들고 가는 케이스도 있음
작은 필드 하나지만, SEO 관점에서 방치하면 조용히 퍼포먼스를 깎아먹는 유형의 버그다.
수정 내용
변경은 src/layouts/Post.astro 한 파일에 집중됐다.
| 항목 | Before | After |
|---|---|---|
Article schema url 값 |
(localhost 포함 절대 URL) | _siteUrl + pathname 조합 |
| 출처 | 런타임 환경 의존 | 사이트 설정값 기준 |
핵심은 런타임에서 흘러들어오는 URL을 그대로 쓰지 않고, 사이트 설정에서 관리하는 _siteUrl 에 현재 페이지의 pathname 만 붙이는 패턴으로 교체한 것이다.
---
// Before: 환경에 따라 달라지는 URL 그대로 사용
const articleUrl = Astro.url.href;
// After: 사이트 기준 URL + pathname 조합
const articleUrl = _siteUrl + Astro.url.pathname;
---
<script type="application/ld+json">
{JSON.stringify({
"@context": "https://schema.org",
"@type": "Article",
"url": articleUrl,
// ...
})}
</script>
이렇게 하면 로컬이든 스테이징이든 빌드 환경이 어디든 간에 url 필드는 항상 _siteUrl 기준으로 고정된다. 개발 서버의 호스트 정보가 절대로 빌드 산출물에 섞이지 않는다.
회고
사실 이런 버그는 "왜 발견이 늦었나"가 더 중요한 질문이다.
로컬에서 개발할 때는 HTML 소스를 열어봐도 schema JSON이 눈에 잘 안 들어오고, 기능 테스트엔 전혀 영향이 없으니 그냥 넘어가기 쉽다. 배포 이후에도 화면 렌더링엔 아무 문제가 없으니 QA에서도 걸리지 않는다. 결국 Search Console이나 Rich Result Test 같은 외부 도구로 검증해보기 전까지는 잠재적으로 계속 살아남는 버그다.
이 유형의 문제를 팀 단위로 막으려면 몇 가지 습관이 필요하다.
- 빌드 후 출력된 HTML에서 schema JSON을 lint로 검사하는 단계 추가
Astro.url.href처럼 환경 의존적인 값을 schema 필드에 직접 쓰는 패턴을 코드리뷰에서 플래그- 배포 직후 주요 페이지를 Rich Results Test로 검증하는 체크리스트 항목화
혼자 작업할 때도 그렇지만 팀으로 운영할 때는 이런 "기능엔 문제 없는데 메타 레이어가 망가진" 케이스를 잡을 안전망을 만들어두는 게 중요하다. 코드 자체는 pinpoint 수정이었지만, 이걸 계기로 schema 관련 검증 흐름을 어떻게 자동화할지 다시 생각해보게 됐다.
끝.
🛒 이 글과 어울리는 추천 상품
*위 링크는 쿠팡파트너스 활동의 일환이며, 일정액의 수수료를 제공받을 수 있습니다.
댓글 0
첫 댓글 달아줘.