Articles

Robots.txt vs Sitemap.xml: How Crawlers Read Your Site

Robots.txt tells crawlers what not to fetch; sitemap.xml tells them what exists. How the two files work together, and where each one fails.

Takina Takina · · 4 min read
Abstract icons representing web platform standards

robots.txt and sitemap.xml are two plain-text files that sit at the root of a website and do opposite jobs: robots.txt tells crawlers which URLs they’re not allowed to fetch, and sitemap.xml tells them which URLs do exist and are worth fetching. Neither one is required for a site to work, and neither one guarantees a page will or won’t end up in a search index — but together they’re the main channel a site has for talking to crawlers before those crawlers ever render a page.

What robots.txt actually controls

A robots.txt file lives at https://example.com/robots.txt and follows the Robots Exclusion Protocol — a set of User-agent blocks with Allow and Disallow rules underneath them:

User-agent: *
Disallow: /admin/
Disallow: /cart/
Allow: /cart/summary

User-agent: GPTBot
Disallow: /

Sitemap: https://example.com/sitemap.xml

Compliant crawlers check this file before fetching anything else from your domain and skip whatever Disallow rules match. The critical caveat: this is opt-in cooperation, not access control. A malicious scraper can simply ignore the file, and disallowing a path in robots.txt does not remove it from search results if other pages link to it — Google may still index the URL with no description, just without crawling its contents. If you need a page genuinely excluded from indexes, that’s a job for a noindex meta tag or HTTP header, which requires the page to be crawlable in the first place so the crawler can see the tag. Robots.txt and noindex solve different problems and are easy to combine incorrectly.

Robots.txt is also where you point crawlers at your sitemap, and where you can rate-limit or block specific bots by user-agent string — useful now that AI training crawlers (GPTBot, CCBot, ClaudeBot, and others) each respect their own user-agent token.

What sitemap.xml actually does

A sitemap is the opposite gesture: instead of hiding paths, it surfaces them. It’s an XML file listing URLs you want crawled, optionally with metadata like last-modified date and priority:

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

Sitemaps matter most for pages that are hard to discover by following links — deep archive pages, a catalog with thousands of SKUs, or a site that’s brand new and has no inbound links yet pointing crawlers toward it. For a small, well-linked site, a sitemap is a nice-to-have; for a large one, it’s often the only reliable way to get every page crawled at all. Search engines still decide independently whether to crawl and index each URL — a sitemap is a hint, not a directive, the same way Disallow is a request rather than an enforcement mechanism.

How the two files interact

robots.txtsitemap.xml
PurposeRestrict crawler accessAdvertise crawlable URLs
FormatPlain text, User-agent rulesXML (or plain text list)
LocationMust be at domain rootReferenced from robots.txt or submitted directly
EnforcementVoluntary compliance onlyVoluntary compliance only
Effect on indexingCan prevent crawling, not indexingCan encourage crawling, not force indexing
Typical sizeA few dozen linesCan span multiple files, up to tens of thousands of URLs each

A well-formed site usually has both, and the sitemap’s location is declared inside robots.txt so crawlers find it without a separate submission step. If a URL is both disallowed in robots.txt and listed in the sitemap, the disallow wins — crawlers won’t fetch it either way, so including it in the sitemap is just noise.

Framework and CDN considerations

Static-site generators like Astro typically generate both files at build time from your route list, which keeps them in sync automatically — a page you add to the content collection appears in the sitemap on the next build without manual editing. If you’re deploying behind a CDN, make sure robots.txt isn’t being cached so aggressively that a rule change takes days to propagate; a short cache TTL on that one file is worth the extra origin requests. Large sitemaps (over 50,000 URLs or 50MB uncompressed, per the sitemap protocol’s own limits) need to be split into a sitemap index file referencing multiple child sitemaps.

Common mistakes

  • Blanket-blocking / during staging, then forgetting to remove it. A Disallow: / left in production after launch is one of the most common self-inflicted deindexing incidents.
  • Treating Disallow as a security boundary. Anything listed in robots.txt is trivially discoverable — don’t use it to “hide” sensitive paths; that just publishes a list of them.
  • Sitemap URLs that 404 or redirect. A sitemap full of stale entries wastes crawl budget and signals a poorly maintained site.
  • Forgetting canonical URLs. If your sitemap lists a URL that isn’t the canonical version (say, a non-trailing-slash duplicate), you’re sending mixed signals about which one to index.

The takeaway

Robots.txt and sitemap.xml aren’t competing standards — they’re complementary, and both are advisory rather than enforced. Robots.txt narrows what crawlers fetch; sitemap.xml widens what they know to look for. Neither controls what actually shows up in a search index — that’s a function of crawling, indexing algorithms, and noindex directives working together — but getting both files right is still the cheapest, most reliable way to make sure a site is crawled the way you intend.

Takina Takina · · 4 min read

npm and pnpm Workspaces: Managing a Monorepo

Workspaces let npm and pnpm manage multiple packages in one repository, sharing a single dependency tree and letting packages reference each other locally.

#JavaScript #Web Development #Developer Tools
Takina Takina · · 5 min read

toSorted, toReversed, with(): JS's New Array Methods

toSorted(), toReversed(), toSpliced(), and with() copy an array instead of mutating it, fixing a long-standing footgun in JavaScript's Array API.

#JavaScript #Web Development #Developer Tools