Operations 10 min read 중급

news.hwmoon.com AdSense 승인 전 준비와 운영 전환 기록

news.hwmoon.com의 Google AdSense 승인 대기 상태에서 연결 코드, ads.txt, 수동 광고 슬롯, 빈 슬롯 제거, 승인 이후 slot ID 적용 절차를 나눠 정리한 운영 기록입니다.

Google AdSense
Site review flow
Astro
Static rendering
Azure Static Web Apps
Production deploy
Analytics dashboard screen representing AdSense readiness checks and publishing site verification
자료 이미지: Photo by 1981 Digital on Unsplash
이 글의 목차
  1. 배경
  2. 문제가 헷갈렸던 이유
  3. 목표 상태
  4. 운영 흐름 다이어그램
  5. 구현 기준
  6. 환경변수 설계
  7. QA 체크리스트
  8. news와 tech를 같은 정책으로 맞춘 이유
  9. 승인 이후 전환 절차
  10. 남은 리스크
  11. 참고 문서

이번 기록은 news.hwmoon.com에 Google AdSense를 붙이면서 정리한 승인 전 준비 사항과 운영 전환 기준이다.

처음에는 “AdSense 코드를 넣었는데 왜 광고가 안 보이지?”처럼 보였지만 실제 상태는 더 분리해서 봐야 했다. ads.txt가 승인되어도 사이트 승인 자체가 준비 중이면 광고는 아직 노출되지 않는다. 또 수동 광고 단위의 slot ID가 없는 상태에서 AdSense <ins> 영역만 미리 렌더링하면 사용자는 빈 광고 박스를 보게 된다.

그래서 이번 대응의 결론은 단순하다.

승인 검토에 필요한 신호는 남기고, 승인 전 빈 광고 슬롯은 공개 화면에서 제거한다.

이 글은 그 결정을 기술적으로 다시 재현할 수 있도록 남기는 runbook이다.

배경

news.hwmoon.com은 기사 자동 생성과 정적 배포가 연결된 미디어 사이트다. AdSense 승인 관점에서는 단순히 광고 스크립트를 넣는 것만으로 끝나지 않는다.

승인 검토 중인 사이트는 최소한 아래 조건을 안정적으로 만족해야 한다.

영역필요한 상태운영상 의미
사이트 연결AdSense account meta 또는 AdSense loader가 head에 있음Google이 사이트 소유와 연결 상태를 확인할 수 있어야 한다.
ads.txtroot에서 Google publisher line을 200으로 반환authorized seller 정보가 공개되어야 한다.
콘텐츠충분한 공개 기사와 명확한 navigation검토자가 사이트 목적과 콘텐츠 품질을 판단할 수 있어야 한다.
정책 페이지About, Privacy, Contact, Editorial Policy광고와 개인정보 처리 기준이 보여야 한다.
UX깨진 링크, 빈 광고 박스, 과도한 placeholder 없음승인 전이라도 독자 경험이 완성된 사이트처럼 보여야 한다.
배포 검증build, route smoke check, live HTML audit로컬 변경과 운영 반영 사이의 차이를 줄여야 한다.

Google 공식 문서 기준으로도 사이트 승인이 완료되기 전에는 광고를 표시할 수 없다. 또한 Auto ads는 AdSense code만으로 동작할 수 있지만, 수동 ad unit은 AdSense code와 별도의 ad unit code가 필요하다.

문제가 헷갈렸던 이유

AdSense 콘솔에는 서로 다른 상태가 같은 화면에 가까이 붙어 나온다.

콘솔 상태의미흔한 오해
ads.txt 승인됨root ads.txt가 Google publisher line을 올바르게 반환함사이트 광고 게재 승인까지 끝났다고 오해하기 쉽다.
사이트 준비 중사이트 검토가 아직 진행 중코드가 잘못돼서 무조건 광고가 안 나오는 것으로 오해하기 쉽다.
광고 단위 없음수동 slot ID가 아직 없음<ins>를 미리 넣으면 곧 채워질 것처럼 기대하기 쉽다.
보고서 0승인 전이거나 노출이 없음배포가 실패했다고 단정하기 쉽다.

이번 상태에서는 ads.txt는 정상이었고, head 코드도 들어가 있었다. 하지만 사이트 승인은 아직 끝나지 않았고, AdSense 광고 단위도 만들어지지 않았다.

따라서 공개 페이지에 빈 광고 영역을 미리 보여주는 것은 운영적으로 맞지 않았다. 검토에는 도움이 되지 않고, 독자에게는 미완성 UI처럼 보이기 때문이다.

목표 상태

목표는 승인 전과 승인 후를 명확히 나누는 것이다.

승인 전에는 다음만 유지한다.

  • <meta name="google-adsense-account">
  • AdSense loader script
  • root /ads.txt
  • Privacy page의 광고 고지
  • 충분한 공개 기사와 sitemap
  • 빈 광고 슬롯 없는 화면

승인 후에는 아래를 추가한다.

  • AdSense에서 Auto ads enable
  • 필요한 경우 ad unit 생성
  • 생성된 slot ID를 환경변수로 주입
  • AdSense <ins> slot 렌더링
  • live 노출, CLS, 모바일 overflow 확인

운영 흐름 다이어그램

AdSense review readiness flow showing head metadata, ads.txt, approval pending state, hidden manual slots before approval, rendered ad units after slot IDs are configured, and deployment QA checks.
AdSense 승인 전에는 검토 신호만 유지하고, 수동 광고 슬롯 DOM은 slot ID가 생긴 뒤에만 렌더링한다.

이 구조에서 중요한 점은 “AdSense script를 넣는다”와 “광고 슬롯을 화면에 만든다”를 분리한 것이다. 전자는 사이트 검토와 Auto ads 준비에 필요하다. 후자는 수동 광고 단위가 실제로 만들어졌을 때만 의미가 있다.

구현 기준

news.hwmoon.com의 공통 레이아웃은 AdSense account와 loader script를 head에 넣는다. 단, PUBLIC_ADSENSE_ENABLED가 꺼져 있거나 client ID가 유효하지 않으면 렌더링하지 않는다.

{adsenseEnabled && hasValidAdsenseClientId && (
  <meta name="google-adsense-account" content={adsenseClientId} />
)}

{allowAdsenseOnPage && hasValidAdsenseClientId && (
  <script
    async
    src={`https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=${adsenseClientId}`}
    crossorigin="anonymous"
  ></script>
)}

수동 광고 위치는 별도 AdSenseSlot 컴포넌트로 제어한다. 이번 대응에서 가장 중요한 조건은 아래 한 줄이다.

const shouldRender = adsenseEnabled && hasValidClientId && hasValidSlotId;

이 조건 때문에 승인 전에는 slot ID가 없으므로 아무 광고 DOM도 만들지 않는다. 즉, 빈 dashed box, pending marker, placeholder, 빈 <ins>가 공개 HTML에 남지 않는다.

환경변수 설계

AdSense 관련 환경변수는 account 연결, root seller 선언, 수동 slot을 분리해서 다룬다.

변수역할승인 전 값
PUBLIC_ADSENSE_ENABLEDAdSense 기능 on/offtrue
PUBLIC_ADSENSE_CLIENT_IDca-pub-* account/client ID실제 publisher client
PUBLIC_ADSENSE_PUBLISHER_IDads.txt에 들어갈 pub-* ID실제 publisher ID
PUBLIC_ADSENSE_SLOT_NEWS_HOME_TOP홈 상단 수동 광고 slot비워둠
PUBLIC_ADSENSE_SLOT_NEWS_HOME_RAIL홈 rail 수동 광고 slot비워둠
PUBLIC_ADSENSE_SLOT_NEWS_ARTICLE_TOP기사 상단 수동 광고 slot비워둠
PUBLIC_ADSENSE_SLOT_NEWS_ARTICLE_MID기사 중간 수동 광고 slot비워둠
PUBLIC_ADSENSE_SLOT_NEWS_ARTICLE_BOTTOM기사 하단 수동 광고 slot비워둠

승인 전에는 account/client와 publisher만 실제 값이어야 한다. slot 변수는 비워두는 것이 맞다. slot ID가 없는 값을 억지로 넣거나 placeholder 문자열을 넣으면 오히려 잘못된 광고 DOM이 생성될 수 있다.

QA 체크리스트

이번 대응에서 로컬 build만 보는 것으로 끝내지 않았다. 정적 사이트는 build 산출물과 실제 운영 HTML이 다를 수 있기 때문에 live 확인까지 포함해야 한다.

단계확인
BuildAstro build가 성공하는지 확인
AdSense auditprivacy disclosure, meta, loader, ads.txt, placeholder 부재 확인
Route checkhome, article, privacy, sitemap, ads.txt가 200인지 확인
Live HTML운영 URL에서 pending marker, blank placement DOM, AdSense slot element가 없는지 확인
Mobile400px 폭에서 빈 광고 박스나 horizontal overflow가 없는지 확인
PipelineAzure Static Web Apps 배포 run이 성공했는지 확인

승인 전 live HTML의 기대값은 아래와 같다.

google-adsense-account: 1
pagead2 loader script: 1
ads.txt: 200
pending marker: 0
blank placement DOM: 0
AdSense slot elements: 0

승인 후 수동 slot ID를 넣으면 마지막 두 값은 바뀐다. 이때는 의도한 위치에만 placement marker와 AdSense slot element가 생기는지 봐야 한다.

news와 tech를 같은 정책으로 맞춘 이유

news.hwmoon.com과 tech.hwmoon.com은 성격이 다르지만 광고 준비 정책은 같아야 한다.

사이트성격AdSense 정책
news.hwmoon.com자동 생성 기사 중심 미디어승인 전 recovery mode와 콘텐츠 품질 관리가 중요
tech.hwmoon.com운영 기록과 runbook 중심 기술 블로그코드 변경, 배포 검증, 근거 문서화가 중요

두 사이트 모두 승인 전에는 연결 신호만 남기고 빈 광고 슬롯은 숨긴다. 승인 후에는 Auto ads 또는 수동 slot ID를 통해 실제 광고 DOM을 렌더링한다.

이렇게 맞춰두면 한쪽 사이트에서 배운 검증 로직을 다른 쪽에도 적용할 수 있다.

승인 이후 전환 절차

AdSense 사이트 상태가 준비됨 또는 광고 게재 가능 상태로 바뀌면 다음 순서로 전환한다.

  1. AdSense의 사이트 기준 Auto ads 설정을 확인한다.
  2. 수동 위치가 필요하면 AdSense에서 display ad unit을 만든다.
  3. 생성된 slot ID를 Azure Static Web Apps 환경변수에 넣는다.
  4. staging 또는 local build에서 AdSense <ins> element가 의도한 위치에만 생기는지 확인한다.
  5. production 배포 후 live HTML과 모바일 화면을 다시 확인한다.
  6. 24~48시간 정도 보고서, Active View, CLS, 모바일 anchor ads 영향을 관찰한다.

수동 slot을 바로 많이 넣기보다 article middle 또는 bottom처럼 레이아웃 충격이 적은 위치부터 시작하는 편이 안전하다. 특히 news article page는 본문 읽기 흐름이 중요하므로 top, mid, bottom을 한 번에 모두 켜기보다 하나씩 켜고 지표를 보는 것이 낫다.

남은 리스크

승인 준비가 끝났다고 해서 운영 리스크가 사라지는 것은 아니다.

리스크대응
사이트 승인 지연head code, ads.txt, sitemap, 충분한 공개 콘텐츠, 정책 페이지를 주기적으로 확인
자동 광고가 과도하게 삽입됨Auto ads format과 위치를 AdSense에서 제한
수동 slot이 모바일 레이아웃을 밀어냄responsive slot, width constraint, live mobile QA 필수
광고 스크립트가 noindex 페이지에 들어감robots가 noindex인 페이지에는 loader를 제외
잘못된 placeholder 값 배포slot ID 정규식과 audit script로 차단

참고 문서

정리하면 이번 작업은 “광고를 붙였다”가 아니라 “승인 전과 승인 후의 렌더링 경계를 만들었다”에 가깝다. AdSense가 아직 준비 중일 때는 사이트 검토에 필요한 신호만 유지한다. 독자에게 빈 광고 박스를 보여주지 않는다. 그리고 승인 후에는 slot ID와 Auto ads 정책을 통해 의도한 위치에서만 광고를 시작한다.

시리즈

Publisher Infrastructure

전체 8편 중 7편입니다. 관련 구축 기록을 순서대로 모아 전체 맥락을 쉽게 확인할 수 있습니다.

  1. 1. Azure DNS와 Zoho Mail로 도메인 이메일 만들기
  2. 2. Synology NAS로 Azure DevOps Self-hosted Agent 운영하기
  3. 3. Pipeline은 성공했는데 Static Web Apps가 404를 냈던 이유
  4. 4. Azure Repos를 운영 원본으로 두고 GitHub를 백업으로 쓰는 전략
  5. 5. Slack 기반 AIOps로 NAS Agent 운영 자동화하기
  6. 6. news.hwmoon.com 기사 자동 발행 중단 재발 방지 기록
  7. 7. news.hwmoon.com AdSense 승인 전 준비와 운영 전환 기록
  8. 8. news.hwmoon.com 배포 중단 원인과 Agent 자가복구 체계 구축 기록

관련 글