XML sitemap analysis and generation — validate an existing sitemap against Google's real rules (50k/50MB caps, lastmod accuracy, extension subtypes), or generate a new one (with index splitting) for a site being built out. Feeds the technical-SEO audit and the sitemap step of the seo-writing pipeline's publish stage.
Scanned 9/11/2026
Install to Claude Code
npx -y skills add trungdo9/ClauKit --skill seo-sitemap --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Seo Sitemap?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/trungdo9-seo-sitemap)More formats (shields.io, HTML) on the badges page.
---
name: seo-sitemap
description: XML sitemap analysis and generation — validate an existing sitemap against Google's real rules (50k/50MB caps, lastmod accuracy, extension subtypes), or generate a new one (with index splitting) for a site being built out. Feeds the technical-SEO audit and the sitemap step of the seo-writing pipeline's publish stage.
allowed-tools: Read, Write, Glob, Grep, WebFetch, Bash
---
# SEO Sitemap — Analysis & Generation
> A sitemap doesn't get pages ranked — it gets them *seen*. Most sitemap problems aren't XML syntax errors; they're a mismatch between what the file claims (200, canonical, indexable) and what's actually true, which is a much easier way to waste a crawl budget than it looks.
## When this skill activates
**Implicit:** "sitemap", "generate sitemap", "sitemap issues", "check my XML sitemap", "why isn't my sitemap being read", "sitemap index".
**Explicit:** "Use the seo-sitemap skill to [task]."
**Routed from:** [[seo-technical]] (sitemap/robots.txt is part of its crawl-and-index check), `/mk:seo audit` (technical phase), [[seo-writing]] Stage 6 publish (a newly published article should land in the site's sitemap — see Cross-references).
## Scope
Covers:
- Analyzing an existing XML sitemap: format validity, size caps, `<lastmod>` accuracy, robots.txt linkage, crawled-vs-listed comparison.
- Extension sitemap subtypes (image / video / news) and their distinct rules.
- Generating a new sitemap (or sitemap index) for a site being built out, including safe-vs-risky programmatic-page judgment calls.
- robots.txt's `Sitemap:` directive and how it interacts with the file itself.
Does NOT cover:
- Crawl budget, render/index issues, Core Web Vitals, and general site architecture → [[seo-technical]].
- Whether a *page* belongs in the sitemap at all (noindex decisions, canonical strategy) → [[seo-technical]]; this skill only flags the mismatch once that decision exists.
- Publishing the article whose URL eventually needs to land in the sitemap → [[seo-writing]] Stage 6 (`references/stage-6-publish.md`) — that stage does not currently trigger a sitemap refresh; see Cross-references.
## Mode 1: Analyze existing sitemap
Before reporting a sitemap missing, check both places it's declared:
1. **robots.txt** — read every `Sitemap:` line (there can be more than one; each is a full absolute URL, not a relative path).
2. **Common paths** — `/sitemap.xml`, `/sitemap_index.xml`, `/wp-sitemap.xml` (WordPress core), `/sitemap-index.xml` — probe these even when robots.txt is silent or a declared URL 404s, since a stale robots.txt entry is common.
Only report "not found" once both the declared and common-path candidates have been checked and none resolve. A declared line that 404s is a finding ("robots.txt points at a dead sitemap"), not proof the site has none.
### Validation checks
- Valid XML format (well-formed, correct namespace).
- Per-file limit: **≤50,000 URLs AND ≤50MB uncompressed** — whichever is hit first triggers a split.
- All listed URLs return HTTP 200 (spot-check a sample on large sitemaps rather than every URL).
- `<lastmod>` is accurate: a valid **W3C Datetime**, reflecting the **last significant content change** (body content, structured data, links) — not a bump on every deploy or a copyright-year edit. Google only trusts `<lastmod>` when it's consistently and verifiably accurate; flag values that are suspiciously uniform (every URL has the identical timestamp) or newer than the page's real last edit.
- No deprecated tags: `<priority>` and `<changefreq>` are both ignored by Google — flag as informational cleanup, not a real issue.
- Sitemap is referenced in robots.txt (see robots.txt interplay below).
- Compare a crawl of the site against the sitemap's URL list; flag pages that exist but aren't listed, and listed URLs that no longer exist.
### Quality signals
- A sitemap index is used once the site exceeds 50k URLs (rather than one file silently truncating).
- Split by content type where it helps triage (pages, posts, images, videos) rather than one undifferentiated list.
- No non-canonical URLs included.
- No noindexed URLs included.
- No redirected URLs included (list the final destination, not the redirect source).
- HTTPS URLs only — no `http://` entries on an HTTPS site.
### Common issues
| Issue | Severity | Fix |
|---|---|---|
| >50k URLs in a single file | Critical | Split into a sitemap index |
| >50MB uncompressed in a single file | Critical | Split into a sitemap index |
| Non-200 URLs listed | High | Remove or fix the broken URLs |
| Noindexed URLs included | High | Remove from the sitemap |
| Redirected URLs included | Medium | Replace with the final destination URL |
| All `<lastmod>` identical | Low | Use real per-page modification dates |
| `<priority>`/`<changefreq>` present | Info | Can remove — Google ignores both |
### Extension sitemaps (image / video / news)
Google documents three subtypes, each with its own schema and rules — validate against the specific subtype, not the generic URL rules:
- **Image** (`http://www.google.com/schemas/sitemap-image/1.1`): only `<image:image>` and `<image:loc>` remain valid, max **1,000** `<image:image>` entries per `<url>`. `<image:caption>`, `<image:geo_location>`, `<image:title>`, and `<image:license>` were deprecated — flag any present as info-level removable clutter.
- **Video**: each `<video:video>` requires `<video:thumbnail_loc>`, `<video:title>`, `<video:description>`, plus either `<video:content_loc>` or `<video:player_loc>` (mRSS is also accepted). Flag deprecated/removed sub-tags (`<video:category>`, `<video:gallery_loc>`, `<video:price>`, `<video:tvshow>`, autoplay/allow_embed player params) as info-level removable — reconfirm against current Google docs before citing an exact removal date, since this area changes.
- **News**: hard cap of **1,000** `<news:news>` entries per file (not the generic 50,000), and only articles from the **last 2 days** belong in it — older articles should be pruned, not left to accumulate. Requires `<news:publication>`/`<news:name>`, `<news:language>`, `<news:publication_date>`, `<news:title>`. Discovery is through Search Console or a robots.txt/sitemap-index reference, same as any other sitemap. When the `news:` namespace is present, apply the 1,000-item cap instead of the generic 50k check.
## Mode 2: Generate a new sitemap
### Process
1. Confirm business type (or infer it from the existing site) — it shapes what URL patterns to expect (products vs. locations vs. articles).
2. Plan the structure interactively with the user: which sections exist, roughly how many URLs each contributes, whether any of them are programmatic (see the safe/risky split below).
3. Apply the location-page scale gate before including any city/location pages: **warn** at 30+ location pages (require 60%+ unique content per page to justify them) and **hard-stop** at 50+ (require explicit user justification — this is the doorway-page range [[seo-technical]] flags in audits).
4. Generate valid XML output.
5. Split at whichever limit hits first — 50,000 URLs or 50MB uncompressed — into a sitemap index once either is exceeded.
6. Write a short structure summary alongside the XML (see Output) so the URL organization is reviewable, not just the raw file.
### Safe programmatic pages (scale these without much worry)
- Integration pages, when each has real setup documentation.
- Template/tool pages, when each has genuinely downloadable or usable content.
- Glossary pages, when each definition runs 200+ words.
- Product pages, when specs/reviews are genuinely unique per product.
- User-profile pages, when the content is real user-generated content.
### Penalty risk (do not scale these into a sitemap without review)
- Location pages where only the city name changes.
- "Best [tool] for [industry]" pages with no industry-specific value.
- "[Competitor] alternative" pages with no real comparison data.
- AI-generated pages with no human review or unique value added.
Including thin pages like these in a sitemap doesn't just risk a ranking penalty on those pages — it invites Google to crawl them more, spending budget that would otherwise go to pages worth indexing.
## Sitemap format
### Standard sitemap
```xml
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>https://example.com/page</loc>
<lastmod>2026-08-25</lastmod>
</url>
</urlset>
```
### Sitemap index (for >50k URLs, or for organizing by content type)
```xml
<?xml version="1.0" encoding="UTF-8"?>
<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<sitemap>
<loc>https://example.com/sitemap-pages.xml</loc>
<lastmod>2026-08-25</lastmod>
</sitemap>
<sitemap>
<loc>https://example.com/sitemap-posts.xml</loc>
<lastmod>2026-08-25</lastmod>
</sitemap>
</sitemapindex>
```
## robots.txt interplay
- A sitemap is declared in robots.txt with a full absolute URL: `Sitemap: https://example.com/sitemap.xml` — never a relative path.
- robots.txt can declare more than one `Sitemap:` line (e.g. one per content type, or one being the sitemap index that fans out to the rest) — read all of them, not just the first match.
- The `Sitemap:` directive is independent of the `Allow`/`Disallow` rules in the same file — a URL can be listed in the sitemap and still be blocked from crawling by a `Disallow` rule elsewhere in robots.txt. That combination is a real finding (the sitemap is advertising a URL the crawler is told not to fetch), not a false positive.
- Search Console's Sitemaps report is the other legitimate way to point Google at a sitemap and doesn't require a robots.txt entry — a site can submit there directly. Prefer having both: robots.txt for any crawler, GSC submission for indexing status and error visibility specific to Google.
## Error handling
- **URL unreachable**: report the HTTP status code and suggest checking whether the site itself is live.
- **No sitemap found**: only after both the robots.txt-declared and common-path candidates have been checked and none resolve — report "not found," not "likely missing."
- **Invalid XML**: report the specific parsing error with a line number where possible, not just "malformed."
- **Rate limiting encountered while crawling for comparison**: back off, report partial results, and note that the comparison is incomplete rather than presenting it as final.
## Key concepts
- **Crawl budget** — the sitemap is a request, not a command; a bloated or inaccurate sitemap spends budget on pages that don't matter and doesn't guarantee the pages that do get crawled sooner.
- **`<lastmod>` trust** — Google only uses `<lastmod>` as a recrawl signal when it's verifiably accurate across the file; a sitemap that lies about freshness (or is uniformly identical) gets the tag ignored entirely, which is worse than not having it.
- **Sitemap index** — a sitemap of sitemaps; the mechanism for exceeding the 50k/50MB single-file caps or for organizing by content type without changing what's actually in each leaf file.
- **Doorway-page risk in a sitemap** — listing thin, swapped-variable pages doesn't just risk a per-page penalty; it's a declaration to Google that these pages are meant to be indexed, which raises their visibility to the spam classifiers described in [[seo-technical]].
## Output
### For analysis
- `plans/marketing/<site>/seo-sitemap-report.md` — validation results, issues list with severity, recommendations.
### For generation
- `sitemap.xml` (or split files plus a `sitemap-index.xml`) written to the location the user specifies.
- A short structure summary (URL count per section, index organization) in the same report file or inline in conversation.
## Cross-references
- `plans/marketing-context.md` — required hub.
- [[seo-technical]] — owns the broader crawl/index/architecture audit this skill's findings feed into; also owns the doorway-page and location-page-scaling judgment this skill applies when generating.
- [[seo-writing]] `references/stage-6-publish.md` — publishes new articles but does not currently trigger a sitemap update; most CMS/SEO-plugin setups (e.g. Yoast/RankMath on WordPress) regenerate the sitemap automatically on publish, but a custom REST target should re-run this skill's analysis mode after a publish batch to confirm new URLs actually landed in the sitemap.
- [[seo-programmatic]] — the safe-vs-penalty-risk page judgment used here in Mode 2 is the same one applied when planning programmatic pages generally.
- `.claude/workflows/marketing-rules.md` — content quality rules.
- `skills/marketing/README.md` — full kit overview.
## Provenance
Imported from `AgriciDaniel/claude-seo` (`seo-sitemap`, v2.2.4) and adapted for KitForge. Dropped: the `claude-seo run sitemap_discovery.py --json` helper invocation — ClauKit ships no bundled Python runtime (the same drop applied across every ported seo-* skill, see the root [[seo]] skill's Provenance); the discovery method it implemented (read robots.txt `Sitemap:` lines through an SSRF-safe fetch, fall back to common paths) is preserved here as plain instructions for Claude to carry out directly. Also dropped: "load industry template from `../seo-plan/assets/`" — ClauKit's `seo-plan` skill ships no `assets/` directory, so Mode 2 plans structure interactively instead of from a template file. Output path changed from a bare `VALIDATION-REPORT.md`/`STRUCTURE.md` to `plans/marketing/<site>/seo-sitemap-report.md`, matching ClauKit's shared output convention.
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!