정적 SEO
정적 HTML 사이트의 SEO 설정을 9가지 카테고리(헤드 메타데이터, 구조화된 데이터, 콘텐츠 품질, Open Graph 이미지, 사이트맵 및 인덱싱, 에이전트 검색, 성능, 리디렉션, CI 검증)로 감사하고 개선합니다. 레시피는 플랫폼 중립적입니다: 원시 <meta> 태그, 원시 JSON-LD, 수동 sitemap.xml, 일반 CI 도구. 감사 프레임워크는 astro-seo와 유사하지만 @jdevalk/astro-seo-graph 구조는 사용하지 않습니다.
코드 레시피는 AGENTS.md에 있습니다 — 특정 수정 사항을 구현해야 할 때 읽으십시오. 이 파일에는 작업 흐름과 감사 체크리스트가 포함되어 있습니다.
작업 흐름
- 프로젝트 감지 — 이것이 정적 사이트인지 확인하고, 빌드 도구를 식별하며, 변경 사항을 적용할 위치를 찾습니다.
- 감사 — 9가지 카테고리를 평가하고 실행 가능한 결과를 생성합니다.
- 개선 — 격차를 해소하기 위해 파일을 생성하거나 수정합니다. 레시피는
AGENTS.md에 있습니다. - 메타데이터 검사 — 스킬이 생성한 모든 짧은 문자열(제목, 설명, 스키마
description필드, FAQ 답변)에 대해metadata-check를 호출합니다. - 확인 — 빌드를 실행하고, 출력을 검증하며, 파일 작업 외의 작업(Search Console, Bing Webmaster Tools, IndexNow 키 제출)에 대해 사용자에게 알립니다.
0단계: 프로젝트 감지
감사 전에 기본 사항을 확인합니다:
- 실제로 정적 사이트인지 확인합니다. 빌드된 HTML을 찾습니다 —
index.html이 리포지토리 루트에 있거나_site/(Jekyll),public/(Hugo / 11ty / Gatsby),dist/(Vite / Astro 정적),out/(output: export가 있는 Next.js) 아래에 있는지 확인합니다. 모든 것이 서버 렌더링(Express, PHP, 동적 경로)된 경우, 이 스킬은 적합하지 않습니다 — Astro는astro-seo를, WP 플러그인 페이지는wp-readme-optimizer를 가리키거나 일반 SEO 감사를 권장합니다. - 소스 빌드 도구를 식별합니다. 헤드 메타데이터 변경 사항을 적용할 위치를 결정합니다:
_config.yml/_layouts/→ Jekyllconfig.toml/config.yaml/themes/→ Hugo.eleventy.js/_includes/→ 11tygatsby-config.js/src/components/SEO.*→ Gatsbynext.config.js(output: 'export') 및pages/_document.tsx→ Next.js 정적 내보내기astro.config.mjs→ Astro (이 경우astro-seo를 대신 사용하십시오)- 빌드 구성 없이 HTML 파일만 있는 경우 → 수동 또는 스크래핑된 사이트(예:
wp-static-clone출력). HTML을 직접 편집하거나 사후 처리 스크립트를 사용합니다.
- 표준 사이트 URL을 확인합니다. 리포지토리에서 프로덕션 원본을 검색합니다 — 일반적으로
_config.yml,config.toml,astro.config또는 레이아웃에 하드코딩되어 있습니다. 누락되었거나, 비어 있거나,localhost인 경우, 다른 모든 작업보다 먼저 차단 문제로 표시합니다. 표준 URL, 사이트맵, OG 이미지 URL 및 JSON-LD@id값은 모두 이 URL에서 파생됩니다. - 배포 대상을 확인합니다.
vercel.json,netlify.toml,wrangler.toml또는public/_headers를 읽어 호스트를 확인합니다. 2단계에서 리디렉션 및 헤더 구문을 결정합니다. - 사이트가 다국어인가요? 로케일 하위 디렉토리(
/en/,/nl/,/de/) 또는 빌드 도구 i18n 구성을 확인합니다. 그렇다면 hreflang이 중요합니다. 그렇지 않으면 건너뜁니다. <head>에 이미 무엇이 있나요? 하나의 빌드된 HTML 파일을 열고 인벤토리를 확인합니다: 제목, 설명, 표준 URL, robots, Open Graph, Twitter 카드, JSON-LD, hreflang. 1단계의 감사는 이미 있는 내용을 참조할 수 있으면 더 빠릅니다.
감지할 수 없는 것만 질문하십시오.
1단계: 감사
각 카테고리를 10점 만점으로 평가합니다. 각 카테고리에 대해 실제 HTML, 구성 또는 템플릿을 인용하는 2-4개의 구체적인 결과를 제시합니다. 각 카테고리 내에서 검사는 계층화됩니다:
- 필수(Must) — 출시 차단 요인입니다. 실패 시 눈에 띄는 SEO 회귀가 발생합니다.
- 권장(Should) — 표준 관행입니다. 건너뛰면 도달 범위가 손실됩니다.
- 좋음(Nice) — 미래 지향적이거나 상황에 따라 다릅니다. 모든 사이트에 기본은 아니지만 유용합니다.
소규모 개인 사이트의 경우 사용자가 전체 처리를 요청하지 않는 한 좋음(Nice) 검사를 건너뜁니다.
1. 헤드 메타데이터(/10)
- 필수 — 모든 페이지에
<title>및<meta name="description">가 있습니다. - 필수 —
<link rel="canonical">가 설정되어 있고, 추적 매개변수가 제거되었으며, 프로덕션 원본에서 파생되었습니다. - 필수 — 페이지가
noindex인 경우 표준 URL이 생략됩니다(Google 권장 사항에 따라). - 필수 —
<title>길이는 30-65자,<meta name="description">길이는 70-200자입니다(SERP 잘림 경계,metadata-check기본값과 동일). - 권장 —
<meta name="robots">에max-snippet:-1,max-image-preview:large,max-video-preview:-1이 포함됩니다. - 권장 — 모든 페이지에 Open Graph(
og:title,og:description,og:image,og:url,og:type,og:site_name)가 있습니다. - 권장 — Twitter 카드 태그(
twitter:card)가 Open Graph와 중복될 때 억제됩니다(Twitter는 자동으로 대체됩니다). - 권장 — 다국어 사이트에서
hreflang대체 항목이 있습니다. 단일 언어면 건너뜁니다. - 권장 — 페이지당 단일
<meta name="robots">및 단일og:image가 있습니다(레거시 도구가 때때로 중복을 생성함).
2. 구조화된 데이터 / JSON-LD(/10)
- 필수 — 모든 중요한 페이지에 적어도 하나의
<script type="application/ld+json">블록이 있습니다. - 권장 — 평평한
Article객체보다는 연결된@graph—@id참조로 연결된 엔티티로BlogPosting이Person작성자 및WebPage부모를 가리킬 수 있습니다. - 권장 —
WebSite,Blog/WebPage,Person/Organization,BlogPosting/Article,BreadcrumbList,ImageObject가 관련 위치에 모두 있습니다. - 권장 — 신뢰 신호:
publishingPrinciples,copyrightHolder,copyrightYear,knowsAbout,SearchAction. - 필수 — Rich Results Test 및 ClassySchema에서 유효성을 검증합니다.
3. 콘텐츠 품질(/10)
- 필수 — 모든 페이지에 고유한
<title>및<meta name="description">가 있습니다(사이트 전체에 중복 메타데이터 없음). - 필수 — 페이지당 정확히 하나의
<h1>이 있습니다. - 권장 —
<title>및<meta name="description">가metadata-check(2.5단계)를 통해 앞부분 로딩, 구체성 및 SERP 적합성에 대해 감사됩니다. - 권장 — 본문 텍스트가 개별 장문 게시물(대량 감사하지 않음)에 대해
readability-check를 통해 감사됩니다. - 권장 — 모든
<img>에alt속성이 있습니다(또는 장식용의 경우alt=""/role="presentation"). - 권장 — 내부 링크가 루트 상대 경로(
/foo/)를 사용하고 절대 경로(https://...)를 사용하지 않습니다 — 도메인 변경 및 미리보기에서도 유지됩니다.
4. Open Graph 이미지(/10)
- 필수 — 모든 페이지에 OG 이미지가 있습니다.
- 필수 — 1200×675(Google Discover 최소 1200px 너비, 16:9 비율).
- 권장 — JPEG(소셜 플랫폼은 OG용 WebP/AVIF를 안정적으로 지원하지 않음).
- 권장 — 빌드 타임에 생성(satori-cli, sharp, ImageMagick, Vercel OG, Bannerbear)되며 페이지별로 수동 업로드되지 않습니다 — 표류를 방지합니다.
- 권장 — URL이 슬러그에서 결정론적으로 파생됩니다(예:
/og/<slug>.jpg) — 페이지를 추가하면 자동으로 이미지가 생성됩니다. - 권장 — 본문 콘텐츠의 모든
<img>에alt속성이 있습니다(또는alt=""/role="presentation").html-proofer또는 이와 유사한 도구를 통해 CI에서 검증됩니다.
5. 사이트맵 및 인덱싱(/10)
- 필수 —
/sitemap.xml(또는 분할 사이트맵의 경우/sitemap_index.xml)에 접근 가능하고, 유효한 XML이며, 모든 URL이 200을 반환합니다. - 필수 — 사이트 루트에
robots.txt가 있고 사이트맵을 참조합니다. - 필수 — RSS 피드가 존재하고
<link rel="alternate" type="application/rss+xml">를 통해 광고되며, 전체 게시물 콘텐츠(잘린 발췌문이 아님)를 포함합니다. - 권장 — 사이트에 여러 콘텐츠 유형이 있는 경우 섹션별로 분할(
sitemap-posts.xml,sitemap-pages.xml) — GSC에서 인덱싱 디버깅이 더 쉽습니다. - 권장 —
<lastmod>가 git 커밋 타임스탬프(가장 정확함), 빌드 타임스탬프(허용 가능) 또는 프론트매터 날짜(최후의 수단)로 채워집니다. CI 체크아웃의 파일 시스템mtime은 잘못되었습니다 — 체크아웃 날짜이지 콘텐츠 날짜가 아닙니다. - 권장 — IndexNow가 통합되었습니다. 사이트 루트의 정적
/<key>.txt경로에 있는 확인 키와 새로운 URL을https://api.indexnow.org/IndexNow로 POST하는 빌드 또는 배포 후크가 있습니다. 프로덕션 호스트에 대한 제출을 게이트합니다(예:CF_PAGES_BRANCH=main,VERCEL_ENV=production,CONTEXT=production) — 조건 없는 제출은 로컬 빌드에서 프로덕션 호스트가 아직 제공하지 않은 URL로 엔드포인트를 호출하여 키가 유효하지 않음(403)으로 표시되고 강제로 순환됩니다.
6. 에이전트 검색(/10)
- 권장 — 콘텐츠 유형별로 전체 말뭉치 JSON-LD를 노출하는 스키마 엔드포인트(
/schema/<type>.json). 리포지토리에 커밋되거나 빌드에 의해 재생성되는 정적 JSON 파일입니다. - 권장 — 모든 스키마 엔드포인트를 나열하는 스키마 맵(
/schemamap.xml),robots.txt에Schemamap:지시문이 있습니다. - 권장 — LLM 소비자를 위해 페이지(제목 + 설명)를 나열하는 사이트 루트의
llms.txt. 정적 텍스트 파일, 페이지당 한 줄. - 권장 — 마크다운 대체 URL(
/blog/post.md가/blog/post/옆에 있음)이 YAML 프론트매터가 포함된 깨끗한 마크다운을 제공하여 AI 에이전트가 HTML 구문 분석 없이 콘텐츠를 소비할 수 있도록 합니다..md형제 파일을 커밋하거나 Cloudflare Transform Rule +Vary: Accept를 사용한 콘텐츠 협상(CF Pages는 사용자 정의 Vary 헤더를 제거하므로 Transform Rule의 URL 재작성만 사용 —AGENTS.md의 레시피 참조). - 권장 — RFC 9727에 따른
/.well-known/api-catalog의 API 카탈로그,application/linkset+json(RFC 9264). 스키마 엔드포인트, 스키마맵, RSS 피드 및 사이트별 API를 나열합니다. 정적 JSON 파일. - 권장 —
robots.txt의 Content Signals 지시문(Content-Signal: ai-train=yes, search=yes, ai-input=yes또는 선호하는 정책). 한 줄, IETF 초안, 낮은 비용. - 권장 —
/*의Link헤더가 검색 파일(사이트맵, llms.txt, api-catalog, schemamap)을 가리킴. 응답 헤더를 읽는 에이전트가 HTML을 구문 분석하지 않고 찾습니다. 호스트별(Cloudflare Pages / Netlify의_headers, Vercel의vercel.json, 기타 서버 구성). - 좋음 —
/.well-known/mcp/server-card.json의 MCP 서버 카드 및/또는/.well-known/agent-card.json의 A2A 에이전트 카드. 사이트가 MCP 서버 또는 A2A 에이전트를 노출하는 경우에만 관련됩니다. - 좋음 — 대화형 엔드포인트를 가리키는
<link rel="nlweb">. NLWeb 채택은 초기 단계입니다. 태그는 한 줄이며 가질 가치가 있지만 2026년에는 점수 차단 요인이 아닙니다. - 좋음 —
/.well-known/ai-catalog.json의 ARD(Agentic Resource Discovery) 카탈로그, 도메인이 제공하는 항목(MCP 서버, A2A 에이전트, OKF 번들, 사이트별 API)을 나열합니다. v0.9 초안이므로 선택 사항입니다 — 그러나 MCP/A2A 카드 및 OKF 번들이 수익을 창출하는 검색 계층입니다. 두 가지 주의 사항: 기본 사양(Agent-Card/ai-catalog)은 미디어 유형 필드 이름을mediaType으로 지정하는 반면 ARD 계층(ards-project/ard-spec)은type으로 지정합니다 — 동일한 값을 가진 두 키를 모두 내보내 항목이 어느 쪽 읽기에서든 유효성을 검증합니다(두 사양 모두 소비자가 알 수 없는 키를 무시하도록 요구함). ARD는 또한 항목당 선택적representativeQueries샘플 프롬프트 배열을 추가합니다. 정적 JSON 파일. - 좋음 — OKF(Open Knowledge Format) 번들: 유형이 지정된 마크다운 개념 파일 트리(페이지당 하나, 경로가 표준 URL을 미러링함)가 단일
.tar.gz로 패키징되고 그 사이에 인덱스 파일이 있습니다. 제공 및 검색은 OKF의 명시적 목표가 아닙니다 — 그것이 ARD 카탈로그 항목의 목적입니다. v0.9 초안, 선택 사항. 아직 등록된 미디어 유형이 없으므로 임시 문자열은application/okf-bundle+gzip입니다(knowledge-catalog#111 및 ard-spec#27에서 추적됨). 임시임을 표시하고 변경될 수 있음을 알립니다. 수동으로 유지 관리하는 사본보다는 사이트의 나머지 부분이 파생되는 동일한 소스에서 생성하는 것이 가장 좋습니다.
7. 성능(/10)
- 필수 — 해시된 에셋이
Cache-Control: public, max-age=31536000, immutable(또는 이에 상응)을 제공하여 한 번만 다운로드되도록 합니다. - 권장 — 기본 웹 글꼴이
<link rel="preload" as="font" crossorigin>을 통해woff2로 사전 로드됩니다. - 권장 —
No-Vary-Search응답 헤더가 캐시 키에서 UTM 매개변수를 제거합니다(/?utm_source=x와/가 캐시 항목을 공유하도록). - 권장 — 첫 페인트 시 렌더링 차단 JavaScript가 없습니다(중요하지 않은 스크립트는 defer 또는 async).
- 권장 — 이미지가 최신 형식(페이지 내 콘텐츠의 경우 WebP/AVIF, OG 카드의 경우 JPEG만)을 사용하고 접힌 부분 아래에서는
loading="lazy"를 사용합니다. - 권장 — 모든 Lighthouse / PageSpeed Core Web Vitals가 녹색입니다: LCP < 2.5초, INP < 200ms, CLS < 0.1.
8. 리디렉션 및 오류 처리(/10)
- 필수 — 존재하고 이동한 모든 URL에 대해
_redirects/vercel.json/ 서버 구성이 유지됩니다. - 필수 — 영구 이동의 경우
301이 아니고302입니다. - 필수 —
404.html(또는 이에 상응)이 404 상태를 반환하고 200을 반환하지 않습니다. 의도적으로 잘못된 URL에 대해curl -I로 확인합니다. - 권장 — 404 페이지에서 URL 오타에 대한 퍼지 일치 제안("혹시...을 찾으셨나요?"). 정적 구현: 유효한 슬러그의 JSON 인덱스를 미리 빌드하고 클라이언트 측에서 퍼지 일치합니다.
9. CI 검증(/10)
- 필수 — CI의 끊어진 링크 검사기. 콘텐츠를 건드리는 모든 푸시에 linkinator 또는 lychee. 내부 및 외부 링크 모두 — 내부는 빌드 회귀를 잡고, 외부는 링크 썩음을 잡습니다. 외부 전용 검사를 위해 주간 실행을 예약합니다.
- 권장 — html-proofer 또는 W3C Validator를 통한 HTML 검증 — 크롤러를 손상시키는 잘못된 마크업을 잡습니다.
- 권장 — 모든 푸시에 Lighthouse CI를 사용하고 점수 임계값을 설정합니다(예: SEO ≥ 95, Performance ≥ 80).
- 권장 — Schema.org JSON-LD validator를 통해 CI에서 JSON-LD 검증(공식 CLI 없음, API에 POST하는 Node 스크립트를 통해 파이프).
- 권장 — CI에서 제목 및 설명 길이 검증: 빌드된 HTML을 살펴보고
<title>및<meta name="description">를 추출하고 범위를 벗어난 항목에 플래그를 지정하는 작은 스크립트입니다.
(Filesystem mtime from CI checkout is wrong — it's the checkout date, not the content date.) *