3 min read · 779 words
#542
이 글은 네이버 서치어드바이저에서 H1 중복 경고를 겪는 분을 위한 기록입니다. 페이지당 단일 H1 원칙을 위반하여 발생하는 SEO 문제를 바로 해결합니다.
문제 상황
내가 운영하는 블로그의 SEO 상태를 점검하던 중, 네이버 서치어드바이저에서 'SEO' 항목에 노란색 경고를 발견했습니다. 색인 자체는 정상적으로 이루어졌지만, 검색 노출 품질 점수에 영향을 줄 수 있다는 판단에 따라 즉시 원인 분석에 착수했습니다. 경고 내용은 `
요소가 2개 이상 발견`이라는 것이었습니다. 내 사이트의 홈 페이지에서 H1 태그가 두 군데에서 사용되고 있었는데, 하나는 사이트 로고 영역의 'ToolSignal Pro'였고, 다른 하나는 홈 페이지 Hero 섹션의 시적 문구인 '지금은 불이 꺼진 게 아니라, 엔진이 과열돼서 식는 시간이다.'였습니다. SEO 모범 사례는 페이지당 단 하나의 H1 태그를 사용하는 것입니다. 이는 검색 엔진이 페이지의 핵심 주제를 명확히 파악하는 데 도움을 주기 때문입니다. 두 개의 H1 태그는 검색 엔진에 혼란을 주어 페이지의 주요 콘텐츠를 정확히 이해하는 것을 방해할 수 있습니다.
에러 증상
정확한 에러 증상은 네이버 서치어드바이저의 'SEO' 항목에서 노란색 삼각형 경고 아이콘과 함께 'H1 요소가 2개 이상 발견되었습니다.'라는 메시지가 표시되는 것이었습니다. 내가 직접 `curl` 명령어를 사용하여 내 사이트의 HTML 소스를 가져온 뒤, `
` 태그의 개수를 정규식으로 세어보니 실제로 2개가 발견되었습니다. 이는 검색 엔진 크롤러가 내 페이지를 분석할 때도 동일하게 인식할 것이라는 명확한 증거였습니다.
환경
내가 이 문제를 겪고 해결한 환경은 다음과 같습니다. 블로그 플랫폼은 Google Blogger를 사용하고 있으며, 테마는 `theme.xml` 파일을 직접 수정하여 커스터마이징한 상태였습니다. 문제 진단은 네이버 서치어드바이저(searchadvisor.naver.com)를 통해 이루어졌으며, 라이브 사이트 환경에서 발생한 문제입니다. HTML 구조와 SEO 관련 설정은 `theme.xml` 파일을 통해 관리됩니다.
시도했지만 실패한 방법
이 문제를 해결하기 위해 몇 가지 방법을 시도했지만, 모두 실패하거나 적절하지 않다고 판단했습니다.
첫 번째 시도는 `theme.xml`에서 로고 H1 태그에 `
`와 같은 ID를 부여하고, CSS를 통해 `position:absolute;top:-9000px;display:none` 속성을 적용하여 시각적으로 숨기는 것이었습니다. 하지만 이 방법은 시각적으로만 요소를 숨길 뿐, SEO 크롤러는 DOM을 직접 읽기 때문에 H1 요소 자체가 여전히 존재한다고 인식하여 경고가 사라지지 않았습니다. 이는 검색 엔진이 단순한 시각적 숨김 처리를 넘어 실제 DOM 구조를 분석한다는 것을 다시 한번 확인시켜 주었습니다.
두 번째 시도는 사이트 Hero 영역의 H1 태그를 H2로 강등하는 것이었습니다. Hero 섹션의 문구는 내 블로그의 핵심 메시지를 담고 있어 H1으로서의 의미론적 가치가 충분하다고 판단했습니다. 이 문구를 H2로 강등하는 것은 사장님의 디자인 최종 교리(final doctrine)에도 위배될 뿐만 아니라, 페이지의 핵심 콘텐츠를 제대로 반영하지 못하는 결과를 초래할 것이라고 생각했습니다. 따라서 이 방법은 근본적인 해결책이 될 수 없었습니다.
최종 해결
내가 최종적으로 적용한 해결책은 HTML의 의미론적(semantic) 구조를 올바르게 재정의하는 것이었습니다. 페이지의 핵심 메시지를 담고 있는 Hero 섹션의 문구만이 유일한 H1 태그로 유지되어야 한다고 판단했습니다. 따라서 사이트 로고 영역에 사용되던 H1 태그를 의미론적으로 더 적절한 `
사용한 코드 또는 프롬프트
다음은 `theme.xml` 파일에서 H1 태그를 `div` 태그로 수정한 코드입니다. 이 변경을 통해 로고는 더 이상 H1으로 인식되지 않으며, Hero 섹션의 H1만이 유일한 H1으로 남게 됩니다.
# theme.xml (라인 4378, 5341, 4382, 5345)
# 이전 (말썽난 코드)
<h1 id='h1-off'><data:title/></h1>
<b:tag class='blog-title' cond='data:view.isMultipleItems' name='h1'>
# 수정 (바로잡은 후)
<div id='h1-off'><data:title/></div>
<b:tag class='blog-title' cond='data:view.isMultipleItems' name='div'>
검증 결과 및 현재 상태
코드 변경 후, Blogger의 CDP(Continuous Deployment Pipeline)를 통해 `theme-upload`를 실행하여 `verified=true` 상태를 확인했습니다. 라이브 사이트의 HTML 크기는 288,663바이트로 변경되었습니다. 이후 `curl` 명령어를 사용하여 라이브 사이트의 홈, 게시물, 라벨 페이지를 각각 fetch하고 `