
AdSense 신청 결과가 왔다. "저가치 콘텐츠"로 거부. 포스트 60개 넘게 작성했는데 저가치라니?
감정적으로 반응하기 전에 원인을 찾아봤다. Google의 관점에서 museck.com을 다시 보니 몇 가지 문제가 보였다. 개인정보처리방침이 없었고, 이용약관도 없었고, About 페이지도 Contact 페이지도 없었다. 하지만 가장 큰 문제는 다른 곳에 있었다.
sitemap.xml을 브라우저에서 열어봤다. URL이 5개뿐이었다. 포스트가 60개 넘는데 5개. 빌드 타임에 DB 쿼리 결과가 캐시되어 버린 것이다. Docker 빌드 과정에서 DB에 접근할 수 없으니 빈 결과가 나오고, 그 빈 결과가 sitemap에 고정된 채 런타임에 갱신되지 않았다.
Google 입장에서 보면 이 사이트에는 페이지가 5개밖에 없다. "저가치 콘텐츠"라는 판정이 나올 만했다.
해결은 간단했다. sitemap.ts에 revalidate를 추가하면 된다. 일반 페이지처럼 sitemap도 ISR을 지원한다.
// src/app/sitemap.ts
export const revalidate = 3600 // 1시간마다 재생성
export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
const payload = await getPayload({ config })
const posts = await payload.find({
collection: 'posts',
where: { _status: { equals: 'published' } },
limit: 0, // 전체 조회
})
// ... 66+ 포스트 URL 동적 생성
}revalidate = 3600으로 1시간마다 sitemap이 재생성된다. 새 포스트를 발행하면 최대 1시간 내에 sitemap에 반영되고, 검색엔진이 다음 크롤링 때 새 URL을 발견한다. 5개에서 66개 이상으로 URL이 늘어났다.
AdSense뿐 아니라 일반적인 사이트 신뢰도를 위해서도 법적 페이지가 필요했다.
/privacy — 개인정보처리방침. 웹사이트와 모바일 앱을 커버하도록 작성했다. App Store 등록 시에도 이 URL이 필요하다./terms — 이용약관. 서비스 이용 조건을 명시한다./about — 회사 소개. 누가 이 사이트를 운영하는지 보여준다./contact — 연락처. 방문자가 피드백을 보낼 수 있어야 한다.이 페이지들은 PayloadCMS의 pages 컬렉션으로 관리한다. 코드 배포 없이 CMS에서 내용을 수정할 수 있다. Footer에도 링크를 추가해서 어느 페이지에서든 접근 가능하게 했다.
AdSense 연동 자체는 두 가지만 추가하면 된다.
// layout.tsx에 스크립트 추가
<Script
async
src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-..."
crossOrigin="anonymous"
strategy="afterInteractive"
/>// public/ads.txt
google.com, pub-..., DIRECT, f08c47fec0942fa0ads.txt는 광고 사기를 방지하기 위한 표준 파일이다. public/ 디렉토리에 두면 루트 경로에서 접근 가능하다. 다만 Next.js의 output: 'standalone' 모드에서는 public 디렉토리가 자동으로 포함되지 않으니 Dockerfile에서 별도로 복사해야 한다.
겉보기 거부 사유와 실제 원인이 다를 수 있다. "저가치 콘텐츠"라고 해서 글을 더 쓸 필요는 없었다. sitemap이 정상적으로 모든 URL을 반환하는지, 사이트의 기본 인프라(법적 페이지, 소개 페이지)가 갖춰져 있는지를 먼저 확인해야 한다.
법적 페이지는 프로젝트 초기에 만들어두는 게 좋다. 나중에 AdSense, App Store, 파트너십 등에서 요구할 때 급하게 만들면 빠뜨리는 내용이 생긴다. sitemap도 마찬가지다 — 배포 후 한 번은 직접 열어서 모든 URL이 정상적으로 나오는지 눈으로 확인하자.
사소해 보이는 것들이 모여서 사이트의 신뢰도를 결정한다. 코드의 품질만큼이나, 사이트가 얼마나 "진지한 서비스"로 보이는지가 중요하다.
Google이 공식적으로 필수라고 명시하지는 않지만, 개인정보처리방침과 이용약관이 없으면 거부될 확률이 높다. App Store 등록 시에도 개인정보처리방침 URL이 필수이므로 미리 만들어두는 게 좋다.
빌드 타임에 한 번만 생성되던 sitemap이 revalidate 주기마다 재생성된다. 새 포스트를 발행해도 sitemap에 자동 반영되어 검색엔진이 빠르게 인식한다. revalidate = 3600이면 1시간마다 갱신된다.
Google은 구체적인 대기 기간을 명시하지 않는다. 거부 사유를 해결한 후 바로 재신청할 수 있지만, 변경 사항이 Google에 반영되려면 최소 2~4주 정도 기다리는 것이 현실적이다.