How to Create an XML Sitemap (and Keep It Indexable)
How to create an XML sitemap: what URLs belong in it, static vs dynamic generation, submitting in Google Search Console, common mistakes, and indexability checks before you ship.
To create an XML sitemap, generate a list of canonical public URLs from the same source of truth as your routes, serve it at a stable path such as /sitemap.xml, and submit that URL in Google Search Console. The file helps search engines discover pages, especially when internal links are thin or a site is new. It does not force indexing, override noindex, or replace crawlable HTML links. This guide covers what belongs in the file, static versus dynamic generation, Search Console submission, common mistakes, and the indexability checks that keep the sitemap aligned with what you actually want in search.
What belongs in an XML sitemap
An XML sitemap is a UTF-8 document in the Sitemaps protocol format. Each entry is a <url> block with a required <loc> (the full canonical URL) and optional fields such as <lastmod>, <changefreq>, and <priority>.
Include URLs that meet all of these conditions:
- Public and indexable. No login wall, no
noindexmeta tag, noX-Robots-Tag: noindexheader. - Canonical. The address matches the self-referencing
rel=canonicalyou emit on the page, not a tracking parameter or filtered variant. - Successful. The URL returns HTTP 200 (or the stable redirect target you treat as the public URL).
- Intended for search. Marketing pages, docs, tools, and blog posts you want discovered. Exclude admin routes, API endpoints, preview hosts, and thank-you screens unless you deliberately index them.
Google's sitemap build guidance stresses listing only URLs you want crawled. If a URL should not appear in results, keep it out of the sitemap and block or noindex it consistently elsewhere.
Pair the sitemap with a sensible robots.txt. Allow crawling of assets the renderer needs, disallow genuine private paths, and reference the sitemap location with a Sitemap: directive. If you need a starting file, use the free robots.txt builder or read how crawl rules interact with indexing in why your site is not showing on Google.
Static vs dynamic sitemaps
Static sitemaps are files committed at build time or exported from a CMS. They are simple for small marketing sites with a fixed route list. The failure mode is drift: engineers ship new templates, but nobody regenerates the file, so Search Console shows fewer discovered URLs than the app serves.
Dynamic sitemaps are generated on request or on a schedule from your database, content registry, or route table. Laravel, Next.js, and most frameworks expose a controller or route that queries the same models that power the site. Orchory's own marketing sitemap is built from the blog registry and public routes so a new post appears automatically when its metadata ships.
| Approach | Best when | Watch for |
|---|---|---|
Static file in public/ |
Few dozen URLs, rare releases | Stale lists after route changes |
| Build-step generator | Jamstack sites with known paths at compile time | lastmod tied to build clock instead of content |
| App route (dynamic) | Blogs, docs, programmatic SEO | Accidentally including drafts or noindex rows |
| Sitemap index + child files | Tens of thousands of URLs | Broken child URLs in the index |
Whichever approach you choose, one rule stays constant: the generator and the HTML templates must read the same eligibility rules. If a page is draft in the CMS, it should not appear in navigation, the sitemap, or internal link modules.
Build a valid sitemap file
A minimal valid document looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>https://example.com/pricing</loc>
<lastmod>2026-10-15</lastmod>
</url>
<url>
<loc>https://example.com/blog/xml-sitemap-guide</loc>
<lastmod>2026-11-01</lastmod>
</url>
</urlset>
Use absolute URLs in <loc>, HTTPS in production, and trailing-slash policy consistent with your canonical tags. Encode reserved characters correctly.
For <lastmod>, prefer W3C datetime or ISO 8601 dates that reflect a real content or template change. Google's documentation notes that lastmod is optional but useful when accurate. Do not bump every URL on each deploy unless every page actually changed.
Declare the sitemap in robots.txt:
Sitemap: https://example.com/sitemap.xml
Developers shipping crawl hygiene alongside content should keep the checklist in SEO for developers next to the generator code.
Submit your sitemap in Google Search Console
After the file is reachable at a 200 response:
- Verify a Domain or URL-prefix property in Google Search Console.
- Open Indexing, then Sitemaps.
- Enter the path (for example
sitemap.xml) and submit. - Wait for the report to show status, discovered URLs, and any errors.
Compare the discovered count with the number of public routes your application expects. A large gap usually means duplicates filtered out, URLs blocked by robots, accidental noindex, or a generator that still points at staging hosts. Search Console's Sitemaps report explains how submitted files are processed separately from the normal crawl schedule.
Submission is not a one-time task. Resubmit or refresh after migrations, subdomain changes, or bulk publishes. For many updated URLs, an accurate lastmod on a refreshed sitemap is often enough; you do not need to request indexing for every line item.
Common XML sitemap mistakes
- Listing non-canonical URLs. Parameterized faceted URLs, print views, and session IDs pollute the file and confuse coverage reports.
- Including noindex or blocked URLs. A sitemap entry does not override
noindexor aDisallowrule. Fix the directive first, then list the URL. - Pointless lastmod churn. Crawlers learn to ignore the field when it changes without a content change.
- Orphan reliance. A sitemap helps discovery but does not replace internal links. See internal linking in HTML for crawl paths.
- Staging leakage. Never expose
staging.example.comentries in a production sitemap. - Wrong host or scheme. Mixed
httpandhttps, or bare domains that redirect in chains, waste crawl budget. - Ignoring sitemap index limits. Split with a sitemap index when you approach 50,000 URLs or 50 MB per file.
Practical rule: If you would not link to the URL from public navigation or body copy, question whether it belongs in the sitemap.
Indexability checks before you submit
Run this checklist on a representative sample whenever the sitemap changes:
- HTTP status. Fetch with
curl -Iand confirm 200 on the final URL. - Robots access. Confirm the URL is not disallowed in
robots.txtand that CSS or JS assets needed for rendering are allowed. - Index directives. Inspect for
noindexin meta tags orX-Robots-Tagheaders. - Canonical. Verify a self-referencing canonical and that alternate variants are excluded from the sitemap.
- Rendered content. Use URL Inspection in Search Console to confirm Google sees meaningful HTML, not an empty shell.
- Internal links. At least one crawlable
<a href>from another discovered page should point to important URLs. - Structured data honesty. JSON-LD should match visible content. For eligible page types, follow the patterns in how to find SERP feature opportunities.
When coverage reports show Crawled - currently not indexed or Discovered - currently not indexed, fix relevance, duplication, or internal paths before resubmitting the same URL repeatedly.
Keep new URLs cite-ready as you ship
A sitemap entry is only the first step. Pages that earn classic results, snippets, or citations in AI answers still need a direct answer, supportable claims, crawlable links, and stable metadata. Orchory ranks page opportunities from your business profile and prepares cite-ready prompts your team can ship in the site's design, with human review before anything goes live.
If you want the research-to-publish loop without adding a separate CMS, read the auto SEO tool workflow, browse the free helpers on Orchory tools, and send your site when you are ready for a first page built with you on a call. Orchory Pro is $990/mo for one plan with no seat limits when you choose ongoing execution after that first page.
For the broader discovery stack, keep Search Console, sitemaps, and robots in the same release checklist as your templates.