Guide · Jul 1, 2026

Sitemaps for Static Sites: GitHub Pages, Netlify, and Vercel

A plain HTML site, or a small static site generator setup, doesn't always come with a sitemap.xml out of the box. If your framework doesn't generate one automatically, search engines are left to discover your pages purely by following links — which works, but slower and less reliably than handing them a map directly.

Do you actually need one?

For a five-page site, probably not urgently — Google will find five interlinked pages on its own without much trouble. For anything with more than a handful of pages, a tool directory, a blog, a documentation set, yes — a sitemap is one of the cheapest SEO wins available, and it costs nothing to add. The real value shows up as your page count grows: new content gets discovered faster, and pages that are only reachable through deep or unusual link paths (an old blog post, a rarely-linked tool page) don't have to rely on a crawler stumbling onto them.

What a sitemap actually does — and doesn't do

A sitemap is a discovery aid, not a ranking mechanism. Listing a URL in your sitemap tells search engines the page exists and gives a rough sense of when it last changed; it does not make that page rank better, and it doesn't guarantee indexing. Think of it as removing "the crawler never found this page" as a possible failure mode — everything else about whether a page gets indexed and ranked still depends on the content itself.

GitHub Pages

GitHub Pages serves whatever static files sit in your repository, so a sitemap.xml just needs to exist at your site root alongside index.html. There's no build step involved — you generate it once, commit it, and update it whenever you add pages. This is deliberately the simplest possible setup: no plugin, no configuration file, just a static XML file sitting next to your other static files.

Netlify and Vercel

Both platforms serve static files the same way GitHub Pages does, so the same approach works: drop sitemap.xml in your publish directory. If you're using a framework with a build step, check whether it has a sitemap plugin — Next.js and most static site generators have one — but a hand-generated file works identically for smaller sites, and it's often simpler than configuring a plugin correctly. The tradeoff: a plugin regenerates automatically on every build, while a hand-generated file needs a manual update when you add pages. For a site that publishes a few times a month, that's a minor chore; for one publishing daily, the plugin route is worth the setup time.

Why sitemap.xml sometimes 404s even though the file is right there

This is the part that catches people off guard: the file shows up fine in your repository on GitHub.com, but https://yoursite.com/sitemap.xml returns a 404. On GitHub Pages specifically, the usual cause isn't the sitemap at all — it's that GitHub Pages runs every site through Jekyll by default, even if you never touched Jekyll or don't know what it is. As part of that build step, Jekyll silently skips certain files, including anything sitting in a folder that starts with an underscore, and it can mishandle plain dotfiles too. What's in your repo and what actually gets deployed aren't guaranteed to be the same thing until you turn that build step off.

The fix is a single empty file: add .nojekyll to the root of your repository, next to index.html and sitemap.xml. It doesn't need any content — its presence alone tells GitHub Pages to skip the Jekyll build and serve exactly what you committed, byte for byte. If you weren't relying on Jekyll templating (front matter, _layouts, Liquid tags) to build your pages in the first place, adding it changes nothing else about your site.

If you've also set up a custom domain, isolate the cause before assuming it's Jekyll: try https://your-username.github.io/your-repo/sitemap.xml directly. If that works while your custom domain still 404s, the problem is DNS/HTTPS propagation on the custom domain, not the Jekyll build — a different fix (and usually just a matter of waiting) than adding .nojekyll.

Netlify and Vercel don't run a Jekyll build, so this exact cause doesn't apply there, but the equivalent failure mode is a mismatched output directory. If your build tool writes the deployable site to dist/ or build/ while your platform's publish directory setting points at public/ (or vice versa), a file that genuinely exists in your source repository simply won't be part of what gets deployed. The tell: it works when you run the site locally (npx serve or similar) but 404s only in production. Check that sitemap.xml sits inside whichever folder your platform is actually configured to publish, not just somewhere in the repo.

Keeping it current without a build step

If you're not using a framework with automatic sitemap generation, the practical habit is to update sitemap.xml at the same time you publish anything new — treat it as part of the "publish a page" checklist rather than a separate task you'll remember to circle back to later. A sitemap that's slightly stale (missing your newest page for a few days) is a minor issue; one that's stale for months starts to undercut the reason you added it in the first place.

After you have the file

Add a line to your robots.txt pointing to it (Sitemap: https://yoursite.com/sitemap.xml), then submit the URL in Google Search Console under Sitemaps. That's the entire process — no crawling delay to wait out on your end, submission is instant even if indexing takes longer. Search Console will also flag any URLs in your sitemap that return errors, which doubles as a lightweight way to catch broken links you didn't know about.

FAQ

I can see sitemap.xml when I browse my repo on GitHub — why does the live URL still 404?

Because the repository file browser shows your source files, not what GitHub Pages actually served after its build step ran. Until you add .nojekyll, Jekyll's default build can drop files that a plain look at the repo won't reveal — presence in the repo and presence in the deployed output are two different things.

Will adding .nojekyll break anything else on my site?

No. It only disables the automatic Jekyll build. If your site is already plain HTML (or output from a generator other than Jekyll), you weren't using Jekyll's templating anyway, so nothing changes except that files it was previously stripping now get served as-is.

My sitemap loads at the .github.io URL but not my custom domain — same fix?

No — that pattern almost always means DNS or HTTPS is still propagating on the custom domain, not a Jekyll/build problem. Test the .github.io URL first to isolate which layer is actually failing before changing anything.

How do I know my sitemap.xml is actually valid once it's live?

Open it directly in a browser first — a 404, an HTML error page, or garbled text all mean it isn't being served correctly, independent of whether the XML itself is well-formed. Once it loads, FreeToolDev's Bulk Sitemap Validator checks the actual XML structure (priority ranges, changefreq values, duplicate URLs, malformed tags) for one or several sitemaps at once.

Generate one now

FreeToolDev's sitemap generator turns a pasted list of URLs into a valid sitemap.xml instantly, and the RSS generator covers the other file most static blogs are missing. If you'd rather not compile the URL list by hand, the Site Crawler & Audit tool can crawl your site automatically and generate the sitemap, RSS feed, and an llms.txt file in one pass.