# SEO — 기술 기반 체크리스트

크롤러가 읽지 못하는 콘텐츠는 존재하지 않는 콘텐츠다. 이 레인의 목표는 하나:
**자바스크립트 없이 받은 HTML에 콘텐츠·메타·구조화 데이터가 전부 있게** 만드는 것.

## 1. 콘텐츠 노출

- [ ] 핵심 페이지가 **비로그인으로 열리는가?** 로그인 월 뒤의 콘텐츠는 색인되지 않는다.
      전부 열기 어려우면 티저(첫 문단·핵심 수치)라도 SSR로 열고 나머지를 게이트한다.
- [ ] `curl -sL <url>`로 받은 HTML에 본문이 있는가? SPA/CSR이면 SSR·SSG·프리렌더 도입이
      1순위다 — 이거 없이는 아래 전부가 무의미하다.
- [ ] ⚠️ **CSR 바일아웃 함정**: SSR 프레임워크에서도 특정 훅·API 사용이 페이지를 통째로
      클라이언트 렌더로 떨어뜨릴 수 있다 (Next.js의 Suspense 없는 useSearchParams 등).
      배포마다 대표 페이지를 curl로 재확인하라 — 본문 글자 수가 갑자기 줄면 사고다.

## 2. 사이트맵

- [ ] sitemap.xml 존재 + robots.txt에서 참조
- [ ] 상세 페이지(제품·글·항목)가 **전부** 들어 있는가 — 목록 페이지만 넣는 실수가 흔하다
- [ ] 5만 URL·50MB 초과가 보이면 **미리 샤딩**하라 (sitemap index + 파트 분할).
      한도 초과 순간 전체가 조용히 무시된다.
- [ ] 새 콘텐츠 유형을 만들면 사이트맵에 넣는 것까지가 출시다 — 빼먹은 유형은 몇 달씩
      색인 밖에 있게 된다 (실측: 필터 페이지 3종 몇 주간 누락)

## 3. 메타

- [ ] 제목 50~60자: 핵심 키워드 앞쪽, 브랜드 뒤쪽
- [ ] 설명 150~160자: 클릭할 이유가 있는 문장 (면책·경고 문구를 설명에 넣지 마라 — CTR만 죽인다)
- [ ] 페이지마다 고유해야 한다 — 템플릿 돌려쓰기로 수백 페이지가 같은 설명이면 중복 판정
- [ ] OG 이미지: 공유 시 보이는 얼굴. 페이지 유형별 동적 생성이 이상적

## 4. 구조화 데이터 (JSON-LD)

- [ ] 페이지 유형에 맞는 스키마: Article, Product, FAQPage, BreadcrumbList, Organization
- [ ] **가시 텍스트와 100% 동일해야 한다** — 화면에 없는 내용을 LD에 넣으면 스팸 판정 위험
- [ ] `@id` 규약: 같은 엔티티는 사이트 전체에서 같은 @id로. 페이지마다 Organization을
      새로 선언하면 엔티티가 분열된다 — 전역 1회 선언 + 참조
- [ ] 검증: Google Rich Results Test 또는 schema.org validator로 배포 후 확인

## 5. URL·응답 위생

- [ ] canonical: 파라미터 변형·중복 경로가 하나의 정본을 가리키게
- [ ] 다국어면 hreflang 상호 참조 (한쪽만 걸면 무효)
- [ ] 없는 페이지는 200이 아니라 404를 — soft 404는 색인 예산을 태운다
- [ ] ⚠️ **404 베이크 함정**: ISR·CDN 캐시 계층에서 일시 장애의 404가 몇 시간씩 구워질 수 있다.
      데이터 조회 실패 시 404를 반환하지 말고 throw(재시도)하라 — "없음"과 "못 가져옴"은 다르다
- [ ] 리다이렉트 체인 1홉 이내

## 6. 성능·자산

- [ ] 이미지 WebP/AVIF + 명시적 width/height (CLS)
- [ ] LCP 대상(히어로 이미지·폰트) preload
- [ ] 로고·아이콘은 무손실 최적화 — 수백 KB 로고가 전 페이지에 실리는 낭비가 흔하다

## 7. 색인 가속

- [ ] IndexNow: 새 페이지·갱신 페이지를 발행 즉시 핑 (Bing·Naver·Yandex 계열이 소비)
- [ ] Google은 IndexNow 미지원 — 사이트맵 lastmod 정확성으로 승부
- [ ] 대량 발행 시 핑도 발행 파이프라인에 내장하라 — 손으로 하는 핑은 반드시 끊긴다
