DailyTools
All articles
SEOMay 25, 20268 min read

XML Sitemaps and robots.txt: The Technical SEO Files Every Website Needs

Two small text files at the root of your domain have an outsized impact on how search engines discover, crawl, and index your content. A developer's guide to getting both right.

DT
DailyTools Editorial · About

The robots.txt file might be the most misunderstood file in web development. It controls what search engine crawlers can access — except it doesn't actually enforce anything. It just asks nicely. A well-behaved crawler like Googlebot will honor it. A scraper or malicious bot will ignore it completely. Understanding what these two files actually do (and what they can't do) is what separates developers who configure them correctly from those who accidentally block their entire site from being indexed — which happens more often than you'd think.

robots.txt: a polite request, not a security mechanism

The robots.txt file lives at the root of your domain (e.g. https://example.com/robots.txt) and uses the Robots Exclusion Protocol — an informal standard from 1994 — to tell crawlers which URL paths they may or may not visit. It's the first thing a well-behaved crawler checks. The key word is 'well-behaved.' robots.txt has no enforcement mechanism. Any bot that wants to ignore it can.

text
# Basic robots.txt example
User-agent: *
Allow: /
Disallow: /admin/
Disallow: /api/
Disallow: /staging/
Disallow: /search?
Disallow: /*.pdf$

# Allow Google to crawl everything except admin
User-agent: Googlebot
Allow: /
Disallow: /admin/

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

robots.txt Directives Explained

  • User-agent: Specifies which crawler the rules apply to. Use * for all crawlers, or name specific bots: Googlebot, Bingbot, GPTBot, etc.
  • Allow: Explicitly permits crawling of a URL path. Only needed to override a broader Disallow rule.
  • Disallow: Blocks crawling of a URL path. An empty Disallow: means 'allow everything.' Disallow: / blocks the entire site.
  • Crawl-delay: Requests crawlers wait N seconds between requests. Honored by Bing and Yandex but ignored by Google (use Search Console to set Google's crawl rate).
  • Sitemap: Points crawlers to your XML sitemap. Can include multiple Sitemap directives for multiple sitemaps.

Hot take: most robots.txt files are over-engineered. A single 'User-agent: * / Allow: /' is correct for 90% of public websites. Everything else is usually paranoia or cargo-culting. That said, the crawling vs. indexing distinction genuinely trips people up: robots.txt blocks crawling, not indexing. If other sites link to a URL you've blocked, Google may still index it — it just can't read the content, so the result shows a bare URL with no snippet. To truly prevent indexing, you need the noindex meta tag or X-Robots-Tag HTTP header instead.

The robots.txt mistakes that actually hurt sites

  • Blocking CSS and JavaScript: If you disallow /assets/ or /static/, Googlebot can't render your pages and may completely misinterpret their content. Always allow crawling of CSS, JS, and images.
  • Blocking your entire site: A misplaced 'Disallow: /' under 'User-agent: *' blocks all crawlers. This often survives from a staging environment config that gets deployed to production.
  • Blocking query strings too broadly: 'Disallow: /?' blocks all parameterized URLs, including legitimate paginated and filtered views that should be crawled.
  • Paths are case-sensitive: 'Disallow: /Admin/' does not block '/admin/' — they're different paths on most web servers.

XML Sitemaps: telling Google what actually exists

An XML sitemap is a list of URLs you want search engines to know about. Crawlers can discover pages by following links, but that only works if pages are linked from somewhere. Newly published content, deep pages, and anything with few internal links might never get found otherwise. The sitemap is your direct line to the crawler: 'these URLs exist, go check them.'

xml
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  <url>
    <loc>https://example.com/</loc>
    <lastmod>2026-05-25</lastmod>
    <changefreq>weekly</changefreq>
    <priority>1.0</priority>
  </url>
  <url>
    <loc>https://example.com/tools/json-formatter</loc>
    <lastmod>2026-05-20</lastmod>
    <changefreq>monthly</changefreq>
    <priority>0.8</priority>
  </url>
</urlset>

Sitemap Elements

  • <loc> (required): The full, canonical URL of the page. Must match the canonical URL exactly — including protocol (https), trailing slashes, and subdomain.
  • <lastmod> (recommended): The date the page was last significantly modified, in ISO 8601 format (YYYY-MM-DD). Google uses this to prioritize crawling recently updated pages. Do not set this to the current date on every build — only update it when the content actually changes.
  • <changefreq> (optional): How frequently the page is expected to change: always, hourly, daily, weekly, monthly, yearly, never. Google largely ignores this in favor of its own crawl patterns.
  • <priority> (optional): A value from 0.0 to 1.0 indicating the page's importance relative to other pages on your site. Only meaningful within your own sitemap — it does not affect ranking against other sites.

What actually matters in a sitemap

  • Include only canonical, indexable URLs — no redirects, no noindex pages, no pages blocked by robots.txt. Including non-indexable URLs wastes crawl budget.
  • Keep sitemaps under 50,000 URLs and 50MB uncompressed — for larger sites, use a sitemap index file referencing multiple child sitemaps
  • Only update <lastmod> when content actually changes. If it's always today's date, Google learns to ignore it entirely.
  • Submit to Google Search Console and Bing Webmaster Tools — passive discovery is slower than direct submission after a big launch or restructure
  • Validate against the sitemaps.org schema before submitting — malformed XML causes the entire sitemap to be silently rejected

Generating Sitemaps Programmatically

Modern frameworks handle sitemap generation out of the box. In Next.js App Router, export a sitemap() function from app/sitemap.ts and it generates the XML at build time. Django has django.contrib.sitemaps. Rails has the sitemap_generator gem. Hugo, Gatsby, and Astro generate sitemaps automatically. There's rarely a reason to write sitemap XML by hand.

typescript
// Next.js App Router — app/sitemap.ts
import type { MetadataRoute } from 'next';

export default function sitemap(): MetadataRoute.Sitemap {
  const tools = getToolsFromRegistry(); // Your tool data source

  return [
    { url: 'https://example.com', lastModified: new Date(), priority: 1.0 },
    ...tools.map(tool => ({
      url: `https://example.com/tools/${tool.category}/${tool.slug}`,
      lastModified: new Date(),
      changeFrequency: 'monthly' as const,
      priority: 0.8,
    })),
  ];
}

Monitoring with Google Search Console

After deploying, Google Search Console is your feedback loop. The Coverage report shows which URLs are indexed, excluded, or erroring — look specifically for 'Excluded by robots.txt' on pages that should be indexed. The Sitemap report shows how many URLs were discovered vs. indexed; a big gap usually signals content quality issues or duplicate content, not a technical crawl problem. The URL Inspection tool and robots.txt Tester let you debug individual URLs.

Try the free tool referenced in this article

XML Sitemap Validator