🗺️ Sitemap Generator

🗺️ Document mode

A URL set is the standard sitemap (one file listing your pages). A sitemap index is the wrapper file you publish when a single URL set would exceed the sitemaps.org 50,000-URL / 50 MB cap.

📝 Input mode

In paste mode, enter one URL per line. To set per-URL fields without using the table, use tab-separated columns: loc, lastmod, changefreq, priority.

⚙️ Defaults (applied when a row's field is blank)

📋 URLs

📋 Paste URLs (one per line)

Optional: append tab-separated columns to override defaults per row — loc <tab> lastmod <tab> changefreq <tab> priority.

🗂️ Child sitemaps

🎨 Pretty-print output

Pretty-print emits indented XML for human readability. Crawlers do not care; compact output shaves a few percent off byte size if you're brushing against the 50 MB cap.

📊 Stats

Entries
{{ urlCount }}
Byte size (UTF-8)
{{ byteSize.toLocaleString() }}

⚠️ Warnings

  • {{ w }}

📤 Generated XML

{{ xml || 'Add at least one URL to generate the sitemap.' }}

Filename suggestion: {{ downloadFilename }}. Submit this URL to Google Search Console and Bing Webmaster Tools.

⚠️

ℹ️ About Sitemap Generator

What an XML sitemap is and why search engines care

An XML sitemap is a structured list of URLs that you publish so search-engine crawlers (Googlebot, Bingbot, DuckDuckBot, YandexBot) can discover and re-crawl your pages efficiently. It is not a ranking signal in itself — it is a discovery hint. A correctly-formed sitemap accelerates the indexation of new URLs, surfaces orphan pages that aren't linked from your navigation, and lets you communicate freshness via <lastmod> so crawlers prioritise revisits intelligently.

This tool generates a sitemap exactly to the sitemaps.org 0.9 protocol — the joint specification published by Google, Bing, and Yahoo. The output is byte-identical between the in-browser preview and the POST /api/tools/seo/sitemap-generator endpoint (Module-First), so what you copy from the panel below is what you would receive from the API.

The five fields the protocol defines for a <url> entry

  • <loc> — the canonical absolute URL of the page. Required. Must include the scheme (https://) and not exceed 2,048 characters.
  • <lastmod> — the last-modified timestamp of the page in W3C Datetime / ISO 8601 format. Either a date (2024-05-27) or a date + time + timezone (2024-05-27T13:45:00+00:00). Optional but strongly recommended — Google uses lastmod as a primary recrawl signal.
  • <changefreq> — a coarse hint for how often the page changes. One of: always, hourly, daily, weekly, monthly, yearly, never. Google explicitly says it ignores this field, but Bing and Yandex still honour it.
  • <priority> — a value between 0.0 and 1.0 indicating the page's relative importance within your sitemap. Like changefreq, Google ignores it; smaller engines still consult it.
  • <xhtml:link> alternates — hreflang annotations for multi-language / multi-region sites. See the Google localized-versions guide for the canonical reference; the tool emits them in the xhtml namespace automatically when at least one entry uses them.

Limits and how to handle them

A single <urlset> document is capped at 50,000 URLs and 50 MB uncompressed. Larger sites split their sitemap across multiple files referenced by a <sitemapindex> document, which itself is capped at the same limits. This tool surfaces a warning the moment either limit is approached so you know it's time to start partitioning.

The recommended partitioning strategy is to group URLs by section (/blog, /products, /docs) so each child sitemap has a stable identity and consistent lastmod cadence. Submit the sitemap index — not the child sitemaps individually — to Google Search Console and Bing Webmaster Tools.

Practical use cases

  • New site launch: publish a sitemap on day one so Google can discover every page without waiting on inbound link signals.
  • Content-heavy blogs: include lastmod for every post so updated articles get re-crawled sooner.
  • E-commerce catalogues: emit a per-category sitemap and roll them up under a sitemapindex so each catalogue change updates a tiny file rather than a 50 MB monolith.
  • International / hreflang sites: use xhtml:link alternates on every URL so Google maps the regional variants to the correct SERP entry.
  • Migration audits: paste a list of legacy URLs and download a sitemap that forces a quick reindexing pass after a domain change.
  • Google Search Console: submit the sitemap URL under Index → Sitemaps and watch the "Discovered URLs" counter climb.

How this tool generates the XML

  • Every loc, hreflang, and href attribute is XML-escaped — &, <, >, ', and " are turned into entity references so the resulting document parses cleanly under every standard XML parser.
  • lastmod is validated against ISO 8601 (date or date + time + timezone); non-conforming values surface as warnings, not silent rewrites.
  • changefreq must be one of the seven enum values; anything else surfaces a warning and is dropped from the output.
  • priority must be a number in [0.0, 1.0]; out-of-range values surface a warning and are dropped.
  • The xhtml namespace is added to <urlset> automatically when at least one URL uses alternates — there's no UI toggle to forget.
  • Byte size is measured as UTF-8 — the same encoding crawlers see on disk — not as JavaScript string.length.

Source references

Limits and practical notes

  • The generator preserves UTF-8 throughout. If your loc values contain non-ASCII characters (Cyrillic, CJK, emoji), they are emitted directly — the XML encoding attribute and the body are consistent.
  • Always submit the sitemap URL to Google Search Console and Bing Webmaster Tools. Auto-discovery via robots.txt (Sitemap: …) is a backup, not a replacement.
  • The 50 MB / 50,000-URL cap applies per file uncompressed. Gzip is allowed at HTTP-transport time but is independent of the per-file size cap.
  • Generation happens in your browser. The same algorithm is exposed by the API endpoint below, using the shared Module-First TypeScript module.

API Usage Example:

POST /api/tools/seo/sitemap-generator
Content-Type: application/json

{
    "urls": [
        {
            "loc": "https://example.com/",
            "lastmod": "2024-05-27",
            "changefreq": "daily",
            "priority": 1
        },
        {
            "loc": "https://example.com/about",
            "lastmod": "2024-05-27",
            "changefreq": "monthly",
            "priority": 0.5
        }
    ],
    "prettyPrint": true
}
Ready