How to Create an XML Sitemap

A hands-on tutorial for creating an XML sitemap from scratch: the required elements, optional tags, encoding rules, sitemap index files, validation, and a complete working example.

This guide walks you through creating an XML sitemap by hand, from the first line of XML to a validated, production-ready file. Whether you're building one manually for a small site or writing code to generate one dynamically, understanding the underlying structure is essential. Every sitemap generator, CMS plugin, and framework library produces the same XML format described here.

The Minimal Valid Sitemap

Let's start with the absolute minimum. A valid XML sitemap needs just three things: the XML declaration, the <urlset> root element with its namespace, and at least one <url> entry with a <loc> tag.

<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  <url>
    <loc>https://example.com/</loc>
  </url>
</urlset>

That's it. This is a complete, valid sitemap containing one URL. Every sitemap you'll ever create is just a more populated version of this structure.

Building the Structure Step by Step

1

Start with the XML declaration

Every XML sitemap begins with:

<?xml version="1.0" encoding="UTF-8"?>

This tells parsers that the file is XML and uses UTF-8 encoding. UTF-8 is required by the Sitemap Protocol -- no other encoding is accepted.

2

Add the urlset root element

The <urlset> element wraps all your URL entries. It must include the Sitemap Protocol namespace:

<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">

</urlset>

This namespace declaration is not optional. Without it, validators and crawlers may reject your sitemap.

3

Add URL entries

Each page on your site gets a <url> element containing a <loc> tag with the full, absolute URL:

<url>
  <loc>https://example.com/</loc>
</url>
<url>
  <loc>https://example.com/about</loc>
</url>
<url>
  <loc>https://example.com/contact</loc>
</url>

The <loc> value must be a fully qualified URL starting with http:// or https://. Relative URLs like /about are not valid.

4

Add optional metadata

For each URL, you can include <lastmod>, <changefreq>, and <priority> tags. Of these, only <lastmod> is worth including:

<url>
  <loc>https://example.com/blog/xml-sitemaps</loc>
  <lastmod>2026-02-19</lastmod>
</url>

More on each optional tag below.

5

Save as sitemap.xml

Save the file with the .xml extension. The conventional filename is sitemap.xml, and it's typically placed in the root directory of your domain so it's accessible at https://yoursite.com/sitemap.xml.

Required Elements Reference

There are only two required elements in the Sitemap Protocol:

<urlset>

The root element. Contains all <url> entries. Must include the namespace declaration.

<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  <!-- url entries go here -->
</urlset>

<url> + <loc>

Each page is represented by a <url> element that must contain exactly one <loc> child with the page's full URL.

<url>
  <loc>https://example.com/pricing</loc>
</url>

Rules for <loc> values:

  • Must be an absolute URL (including protocol)
  • Must start with the same protocol and domain as the sitemap's location
  • Must be properly XML-encoded (see encoding section below)
  • Maximum length: 2,048 characters

Optional Elements Reference

<lastmod> -- Recommended

The date the page was last meaningfully modified.

<lastmod>2026-02-19</lastmod>

Accepted formats:

  • Date only: 2026-02-19
  • Date and time: 2026-02-19T14:30:00+00:00
  • Date and time (UTC): 2026-02-19T14:30:00Z

Google uses lastmod to prioritize which pages to re-crawl -- but only when the dates are accurate. If you update lastmod on every regeneration regardless of actual changes, Google will eventually ignore it.

Only update lastmod when content actually changes

A meaningful change means the page's visible content changed. Updating a sidebar widget or changing a CSS class doesn't count. Use real content modification dates from your database or file system.

<changefreq> -- Not Recommended

A hint about how frequently the page changes.

<changefreq>weekly</changefreq>

Valid values: always, hourly, daily, weekly, monthly, yearly, never.

Google ignores this tag. Their documentation explicitly says so. Googlebot determines crawl frequency based on its own analysis, not your suggestions. You can include it for other crawlers, but it won't affect Google's behavior.

<priority> -- Not Recommended

A relative priority from 0.0 to 1.0.

<priority>0.8</priority>

Google also ignores this tag. In theory, it tells crawlers which pages on your site are most important relative to each other. In practice, everyone sets their homepage to 1.0 and the rest to 0.8, which makes the data useless. Skip it.

ElementRequired?Google Uses It?Recommendation
<urlset>YesYesAlways include
<url> + <loc>YesYesAlways include
<lastmod>NoYes (when accurate)Include with real dates
<changefreq>NoNoOmit
<priority>NoNoOmit

Encoding Requirements

XML sitemaps must follow XML encoding rules. This trips people up more than you'd expect.

URL Encoding

URLs in your sitemap must be entity-escaped for XML. The most common characters that need escaping:

| Character | XML Entity | Example | |-----------|-----------|---------| | & | &amp; | /search?q=test&amp;page=2 | | ' | &apos; | /name/O&apos;Brien | | " | &quot; | Rare in URLs | | > | &gt; | Rare in URLs | | < | &lt; | Rare in URLs |

Non-ASCII characters should be percent-encoded in the URL itself (e.g., spaces as %20), then the resulting URL should be XML entity-escaped.

File Encoding

The file must be saved as UTF-8. Most text editors default to UTF-8, but if you're generating sitemaps programmatically, make sure your output stream uses UTF-8 encoding.

Validate your sitemap encoding

Catch encoding errors, malformed URLs, and XML syntax issues before search engines do.

Complete Example File

Here's a realistic sitemap for a small business website:

<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  <url>
    <loc>https://acmecorp.com/</loc>
    <lastmod>2026-02-19</lastmod>
  </url>
  <url>
    <loc>https://acmecorp.com/about</loc>
    <lastmod>2026-01-10</lastmod>
  </url>
  <url>
    <loc>https://acmecorp.com/services</loc>
    <lastmod>2026-02-01</lastmod>
  </url>
  <url>
    <loc>https://acmecorp.com/services/web-design</loc>
    <lastmod>2026-02-01</lastmod>
  </url>
  <url>
    <loc>https://acmecorp.com/services/seo</loc>
    <lastmod>2026-02-01</lastmod>
  </url>
  <url>
    <loc>https://acmecorp.com/portfolio</loc>
    <lastmod>2026-02-15</lastmod>
  </url>
  <url>
    <loc>https://acmecorp.com/blog</loc>
    <lastmod>2026-02-18</lastmod>
  </url>
  <url>
    <loc>https://acmecorp.com/blog/xml-sitemaps-guide</loc>
    <lastmod>2026-02-18</lastmod>
  </url>
  <url>
    <loc>https://acmecorp.com/blog/seo-basics</loc>
    <lastmod>2026-01-25</lastmod>
  </url>
  <url>
    <loc>https://acmecorp.com/contact</loc>
    <lastmod>2025-12-01</lastmod>
  </url>
  <url>
    <loc>https://acmecorp.com/pricing</loc>
    <lastmod>2026-02-10</lastmod>
  </url>
</urlset>

Creating a Sitemap Index

If your site has more than 50,000 URLs (or you want to organize sitemaps by content type), you need a sitemap index file that references individual sitemap files.

The Index File

<?xml version="1.0" encoding="UTF-8"?>
<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  <sitemap>
    <loc>https://acmecorp.com/sitemap-pages.xml</loc>
    <lastmod>2026-02-19</lastmod>
  </sitemap>
  <sitemap>
    <loc>https://acmecorp.com/sitemap-blog.xml</loc>
    <lastmod>2026-02-18</lastmod>
  </sitemap>
  <sitemap>
    <loc>https://acmecorp.com/sitemap-products.xml</loc>
    <lastmod>2026-02-15</lastmod>
  </sitemap>
</sitemapindex>

Rules for Sitemap Index Files

  • Each child sitemap can contain up to 50,000 URLs
  • Each child sitemap must not exceed 50MB uncompressed
  • The index file itself can reference up to 50,000 child sitemaps (giving you a theoretical maximum of 2.5 billion URLs)
  • Child sitemaps must be on the same domain as the index file
  • The <lastmod> in the index should reflect the most recent modification in that child sitemap

Validating Your Sitemap

Before submitting your sitemap to search engines, validate it. Errors in your XML will cause crawlers to reject the entire file.

What to Check

Well-formed XML

Every opening tag has a closing tag. Elements are properly nested. No stray characters outside of elements.

Correct namespace

The <urlset> element includes xmlns="http://www.sitemaps.org/schemas/sitemap/0.9".

Valid URLs

Every <loc> value is a fully qualified URL with correct encoding. No relative paths, no broken URLs.

Proper encoding

The file is UTF-8 encoded. Special characters in URLs are XML entity-escaped.

Within size limits

No more than 50,000 URLs per file. No larger than 50MB uncompressed.

URLs return 200

Every URL in the sitemap should return a 200 status code. No 404s, no redirect chains.

Validation Methods

XML validators check that your file is well-formed XML. Any XML validator works -- they're not sitemap-specific.

Sitemap-specific validators check both XML validity and Sitemap Protocol compliance (correct namespace, valid elements, proper URL format).

Google Search Console validates your sitemap when you submit it and reports any errors it finds.

After Creating Your Sitemap

Once your sitemap file is ready and validated:

  1. Upload it to your web server's root directory
  2. Verify it's accessible at https://yoursite.com/sitemap.xml
  3. Add Sitemap: https://yoursite.com/sitemap.xml to your robots.txt
  4. Submit it in Google Search Console
  5. Submit it in Bing Webmaster Tools

Then keep it updated. A sitemap that doesn't reflect your current site is worse than no sitemap at all, because it sends search engines to URLs that may not exist anymore and fails to include your newest content.


An XML sitemap is just a list of URLs in angle brackets. Get the structure right, keep the URLs current, and let search engines do the rest.

Validate your XML sitemap

Check your sitemap for errors, broken URLs, and indexing issues. Free instant validation.