Repository navigation
Sitemap: real lastmod dates, no duplicates, no tag pages - #645
Conversation
The sitemap library stamped the time of the request as lastmod on every entry that had no date, which was everything but posts. The handler now builds the XML with encoding/xml, as the RSS feed does: pages carry their own update time, the home page and post listings carry their newest post's, and an entry with no known date has no lastmod. Each URL is listed once (a listing and its page shared a path), tag pages are left out since they only re-list posts already present, and changefreq/priority are dropped as search engines ignore them. Removes go-sitemap-generator and its two dependencies. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
There was a problem hiding this comment.
Copilot review overview
🟢 Approval recommended
The sitemap rewrite is self-contained, logically correct, consistent with the existing RSS pattern, cleanly removes the dependency, and is backed by comprehensive updated tests with no issues found.
Review effort: Balanced
Findings: None
What changed in this PR
This PR rewrites /sitemap.xml generation to fix three problems observed on a live site: lastmod being set to the request time for everything except posts, /posts being listed twice, and tag pages dominating the sitemap (527 of 648 URLs). It replaces the go-sitemap-generator dependency with a hand-built encoding/xml approach matching the existing RSS feed pattern.
Changes:
- Build the sitemap XML directly with
encoding/xml; setlastmodto each page's own update time (or the newest post's for the home page and listings), omitting it when unknown instead of defaulting totime.Now(). - Deduplicate URLs by site-relative path and stop listing tag pages,
changefreq, andpriority. - Remove
go-sitemap-generatorand its transitive dependencies; expandTestSitemapto assert the new behavior.
| File | Description |
|---|---|
| blog/blog.go | Replaces stm-based sitemap with encoding/xml structs, single GetPosts call, path-based dedup, listing/home lastmod from newest post, and tag-page removal. |
| blog/blog_test.go | Adds a /posts page to test dedup; asserts home/listing lastmod, single /posts entry, and absence of /tag/ URLs. |
| go.mod | Drops the go-sitemap-generator direct dependency and two now-unused indirect deps. |
| go.sum | Removes checksums for the dropped dependency and its transitive deps. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Problem
On a live site (648 URLs):
lastmodset to the time of the request, because go-sitemap-generator fills intime.Now()when no date is given. Search engines learn to ignore alastmodthat always says "just now"./postswas listed twice: once as a page, once as a post type listing.Changes
Sitemapbuilds the XML withencoding/xml, as the RSS feed does.lastmodis the page's own update time, or the newest post's for the home page and post listings; it is omitted when not known.changefreqandpriorityare dropped; Google and Bing ignore both.go-sitemap-generatorand its two transitive dependencies.Testing
TestSitemapnow also asserts the home and listinglastmodvalues, a single/postsentry, and no/tag/URLs.go test ./...passes.🤖 Generated with Claude Code