네이버 서치어드바이저 소유확인과 GA4 연결, 정적 블로그에서 하는 법
네이버 서치어드바이저 소유확인 두 가지 방식의 차이, Cloudflare Pages에서 HTML 파일 방식이 막히는 이유, Astro 블로그에 GA4 gtag를 설치하고 수집까지 검증하는 과정을 이 블로그에 직접 적용하며 정리했습니다.
블로그를 열고 한 달쯤 지나 구글 서치콘솔은 붙어 있는데, 네이버에서는 검색이 안 되고 방문자가 몇 명인지도 모르는 상태라는 걸 알았습니다. 이 블로그 이야기입니다. 그래서 네이버 서치어드바이저 소유확인과 GA4 설치를 직접 진행했고, 그 과정에서 함정을 두 개 밟았습니다. 하나는 호스팅의 리다이렉트가 네이버 확인 파일을 가로채는 문제, 하나는 Astro가 분석 스크립트를 번들러로 가져가 버리는 문제입니다. 같은 조합(정적 사이트 생성기 + Cloudflare Pages)을 쓰는 분들이 그대로 따라 할 수 있게 순서대로 정리합니다.
네이버 서치어드바이저 소유확인 방법 두 가지
서치어드바이저(searchadvisor.naver.com)에 사이트를 등록하면 소유확인부터 요구합니다. 방법은 두 가지입니다. 네이버가 발급한 HTML 확인 파일을 사이트 루트에 업로드하거나, 발급된 메타 태그를 홈페이지 head에 넣거나. 네이버 화면에는 HTML 파일 업로드 방식을 권장한다고 안내돼 있습니다.
HTML 파일 방식은 naver로 시작하는 확인 파일을 내려받아
https://내도메인/naver확인코드.html 주소로 접근되게 올리는 방식입니다. 메타 태그
방식은 아래 한 줄을 head에 넣습니다.
<meta name="naver-site-verification" content="발급받은 확인 코드" />
구글 서치콘솔의 google-site-verification 메타 태그와 같은 원리라서, 서치콘솔을
메타 태그로 통과해 봤다면 낯설지 않습니다. 어느 쪽이든 적용하고 배포까지 마친 뒤
서치어드바이저의 소유확인 버튼을 눌러야 판정이 납니다.
Cloudflare Pages에서 HTML 파일 방식이 막히는 이유
이 블로그는 Cloudflare Pages에서 서빙됩니다. 확인 파일을 루트에 올리고 해당 주소를
호출해 보니 파일 내용 대신 HTTP 308 응답이 돌아왔습니다. Pages가 주소를 깔끔하게
유지하려고 /파일명.html 요청을 확장자 없는 /파일명으로 리다이렉트하기
때문입니다. 리다이렉트를 따라가면 내용은 정상적으로 나옵니다. 문제는 검증봇이
따라가 줄지를 사이트 쪽에서 통제할 수 없다는 점입니다.
네이버가 확인하는 주소는 .html이 붙은 원래 주소입니다. 봇이 308을 따라가면
통과하고, 안 따라가면 실패합니다. 결과를 운에 맡기는 셈이라, 저는 확인 파일을
올려둔 채로 판정은 메타 태그 방식으로 받는 쪽을 택했습니다. 메타 태그는 홈페이지
자체에 붙어 있어 리다이렉트가 개입할 틈이 없습니다.
정적 사이트 생성기의 공통 레이아웃에 넣으면 모든 페이지에 함께 들어갑니다. Astro라면 이런 모양입니다.
<!-- src/layouts/Base.astro의 head 안 -->
<meta name="google-site-verification" content="서치콘솔 확인 코드" />
<meta name="naver-site-verification" content="서치어드바이저 확인 코드" />
Astro에 GA4 gtag 설치하기, is:inline이 필요한 이유
GA4 쪽은 관리 화면에서 웹 스트림을 만들면 측정 ID(G-로 시작)와 함께 gtag.js
스니펫을 발급해 줍니다. 이 스니펫을 그대로 붙이면 되는데, Astro에서는 한 가지를
더 챙겨야 합니다. Astro는 컴포넌트 안의 <script>를 기본적으로 자기 번들 시스템으로
가져가 모듈로 처리합니다. 최적화에는 좋은 동작이지만, 발급받은 스니펫이 원문 그대로
출력된다는 보장이 사라집니다. 외부 스크립트 로더와 전역 함수 선언에 기대는 gtag
같은 코드는 is:inline 지시자를 붙여 손대지 말라고 알려줘야 합니다.
<!-- Google tag (gtag.js) -->
<script is:inline async src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXXXX"></script>
<script is:inline>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-XXXXXXXXXX');
</script>
정적 사이트라는 점도 잊기 쉬운 부분입니다. 태그는 빌드 시점에 HTML로 구워지므로, 레이아웃에 태그를 넣었어도 다시 빌드해서 배포해야 실제 사이트에 반영됩니다. 소스는 고쳤는데 소유확인이 계속 실패한다면 배포가 안 나간 경우가 흔합니다.
GA4 수집을 확인하는 방법, 소스 보기로는 모자란 이유
페이지 소스에 스니펫이 보이는 것과 수집이 되는 것은 다른 이야기입니다. 스니펫이 있어도 로더가 차단되거나 측정 ID가 틀리면 데이터는 쌓이지 않습니다. 판정 기준은 수집 요청 자체로 잡는 게 정확합니다.
브라우저 개발자 도구의 네트워크 탭을 열고 사이트에 접속해 두 가지를 확인합니다.
googletagmanager.com/gtag/js?id=G-... 로더가 200으로 로드되는지, 그리고
google-analytics.com/g/collect 요청이 나가면서 파라미터에 자신의 측정 ID(tid)와
page_view 이벤트가 실리는지. 이 블로그에서는 배포 직후 헤드리스 브라우저로 접속해
tid=G-...가 담긴 collect 요청이 나가는 것까지 보고 설치 완료로 판정했습니다.
GA4 관리 화면의 실시간 보고서에서 접속자가 잡히는 것으로 이중 확인하면 됩니다.
소유확인 다음, 사이트맵과 RSS 제출
소유확인이 통과되면 서치어드바이저의 요청 메뉴가 열립니다. 여기서 사이트맵과 RSS를 제출합니다. 사이트맵은 사이트 전체 구조를 알려주고, RSS는 새 글을 알려줍니다. 네이버는 RSS 쪽 반영이 빠른 편이라 블로그라면 둘 다 넣는 쪽이 좋습니다.
Astro는 공식 사이트맵 통합(@astrojs/sitemap)을 켜두면 빌드마다
/sitemap-index.xml을 자동 생성합니다. robots.txt에도 사이트맵 주소를 선언해 두면
서치어드바이저에 제출하기 전에도 크롤러가 스스로 찾을 수 있습니다.
# robots.txt
Sitemap: https://내도메인/sitemap-index.xml
이 블로그 기준으로 제출한 값은 사이트맵 sitemap-index.xml, RSS rss.xml 두
개였습니다. 제출 후 반영까지는 시간이 걸리므로, 수집 현황은 서치어드바이저의 리포트
메뉴에서 며칠 두고 확인하면 됩니다.
순서 요약
같은 구성을 만들려면 이 순서입니다. 서치어드바이저에 사이트 등록, 메타 태그 발급받아
공통 레이아웃 head에 추가, GA4 웹 스트림 만들어 gtag 스니펫을 is:inline으로 추가,
빌드와 배포, 소유확인 버튼 클릭, collect 요청으로 GA4 수집 검증, 사이트맵과 RSS
제출. 함정은 두 곳입니다. 호스팅이 .html을 리다이렉트하면 소유확인은 메타 태그로,
Astro에서 분석 스크립트는 반드시 is:inline으로. 🐹
자주 묻는 질문
네이버 서치어드바이저 소유확인은 어떤 방식으로 하는 게 좋나요?
네이버는 HTML 확인 파일을 루트에 업로드하는 방식을 권장하지만, 호스팅이 .html 요청을 리다이렉트로 처리하면 검증에 실패할 수 있습니다. 메타 태그 방식은 홈페이지 head에 한 줄을 넣는 것으로 끝나고 리다이렉트의 영향을 받지 않아, 정적 호스팅에서는 메타 태그 방식이 확실합니다.
소유확인 메타 태그는 어디에 넣나요?
사이트 홈페이지의 head 섹션 안에 서치어드바이저가 발급한 meta name="naver-site-verification" 태그를 붙여 넣습니다. 정적 사이트라면 공통 레이아웃 파일의 head에 한 번 넣으면 모든 페이지에 들어갑니다. 넣은 뒤 배포까지 마쳐야 서치어드바이저의 소유확인 버튼이 통과됩니다.
Cloudflare Pages에서 네이버 HTML 확인 파일이 실패하는 이유가 뭔가요?
Cloudflare Pages는 주소를 깔끔하게 유지하려고 /파일명.html 요청을 확장자 없는 /파일명 주소로 308 리다이렉트합니다. 파일 내용 자체는 리다이렉트를 따라가면 정상적으로 나오지만, 검증봇이 리다이렉트를 따라가지 않으면 소유확인이 실패합니다. 이 경우 메타 태그 방식을 쓰면 됩니다.
Astro 블로그에 GA4는 어떻게 설치하나요?
공통 레이아웃의 head에 GA4가 발급한 gtag.js 스니펫을 넣되, script 태그에 is:inline 지시자를 붙입니다. Astro는 컴포넌트 안의 script를 기본적으로 번들링 대상으로 처리해서, is:inline 없이 넣으면 스니펫이 원문 그대로 출력되지 않아 수집이 되지 않을 수 있습니다.
GA4가 실제로 수집되는지 어떻게 확인하나요?
두 가지로 확인합니다. GA4 관리 화면의 실시간 보고서에서 접속이 잡히는지 보는 방법과, 브라우저 개발자 도구 네트워크 탭에서 google-analytics.com/g/collect 요청에 자신의 측정 ID(tid 파라미터)와 page_view 이벤트가 실려 나가는지 보는 방법입니다. 페이지 소스에 스크립트가 보이는 것만으로는 수집 여부를 알 수 없습니다.
네이버에 사이트맵과 RSS는 왜 둘 다 제출하나요?
사이트맵은 사이트 전체 구조를, RSS는 최신 글을 알려주는 통로입니다. 네이버 서치어드바이저는 요청 메뉴에서 둘 다 받는데, RSS 쪽이 새 글 반영이 빠른 편이라 블로그라면 둘 다 제출하는 쪽이 유리합니다.