Per-collection sitemaps with index and lastmod#431
Conversation
Split the single flat sitemap into a sitemap index at /sitemap.xml
with per-collection child sitemaps at /sitemap-{collection}.xml.
Each index entry includes <lastmod> from the most recently updated
content in that collection. Individual URL entries include <lastmod>.
Dropped <changefreq> and <priority> (ignored by Google).
The handler now returns data grouped by collection with url_pattern,
and accepts an optional collectionSlug filter for the per-collection
route to query only the requested collection.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
🦋 Changeset detectedLatest commit: c196bf6 The changes in this PR will be included in the next version bump. This PR includes changesets to release 9 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@emdash-cms/admin
@emdash-cms/auth
@emdash-cms/blocks
@emdash-cms/cloudflare
emdash
create-emdash
@emdash-cms/gutenberg-to-portable-text
@emdash-cms/x402
@emdash-cms/plugin-ai-moderation
@emdash-cms/plugin-atproto
@emdash-cms/plugin-audit-log
@emdash-cms/plugin-color
@emdash-cms/plugin-embeds
@emdash-cms/plugin-forms
@emdash-cms/plugin-webhook-notifier
commit: |
There was a problem hiding this comment.
Pull request overview
This PR updates EmDash’s sitemap generation to produce a sitemap index (/sitemap.xml) with one child sitemap per SEO-enabled collection, and adds per-collection sitemap endpoints that include <lastmod> values.
Changes:
- Refactors
handleSitemapDatato return sitemap entries grouped by collection (withurlPattern+ per-collectionlastmod) and adds optionalcollectionSlugfiltering. - Updates
/sitemap.xmlto emit a<sitemapindex>pointing at/sitemap-{collection}.xmlendpoints. - Adds a new per-collection sitemap route and wires it into Astro route injection + middleware public-runtime routing.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/core/tests/integration/seo/seo.test.ts | Updates existing SEO integration tests and adds coverage for urlPattern, collection lastmod, and collectionSlug filtering. |
| packages/core/src/astro/routes/sitemap.xml.ts | Switches sitemap output from a single <urlset> to a <sitemapindex> with per-collection children and <lastmod>. |
| packages/core/src/astro/routes/sitemap-[collection].xml.ts | Introduces the per-collection sitemap <urlset> endpoint that builds URLs using the collection url_pattern. |
| packages/core/src/astro/middleware.ts | Treats /sitemap-{collection}.xml as a public runtime route (so runtime is initialized for sitemap requests). |
| packages/core/src/astro/integration/routes.ts | Injects the new /sitemap-[collection].xml route into the Astro integration. |
| packages/core/src/api/handlers/seo.ts | Refactors sitemap data aggregation to group by collection, include url_pattern, and compute collection-level lastmod. |
| packages/core/src/api/handlers/index.ts | Re-exports the new SitemapCollectionData type. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
Thanks! Could you address copilot's comments, and ask Claude to use the PR template |
…hten regex
- SitemapContentEntry now returns slug and id separately instead of
collapsing them into identifier, so URL patterns using {id} work
- Per-collection sitemap route interpolates both {slug} and {id}
placeholders, matching interpolateUrlPattern behavior elsewhere
- Middleware regex for sitemap collection routes now matches
validateIdentifier rules (no hyphens allowed in collection slugs)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
All done. |
What does this PR do?
Refactors sitemap generation to produce a sitemap index (
/sitemap.xml) with one child sitemap per SEO-enabled collection (/sitemap-{collection}.xml), each including<lastmod>values.Per-collection sitemaps make it easier to spot template and content type issues in Google Search Console, since each collection shows as a separate sitemap.
Related discussion: #408
Type of change
Checklist
pnpm typecheckpassespnpm --silent lint:json | jq '.diagnostics | length'returns 0pnpm testpasses (or targeted tests for my change)pnpm formathas been runAI-generated code disclosure
Screenshots / test output
Changes:
/sitemap.xmlnow serves a<sitemapindex>with one<sitemap>entry per SEO-enabled collection, each with<lastmod>/sitemap-{collection}.xmlroutes serve per-collection<urlset>with<loc>and<lastmod>per URLhandleSitemapDatareturns bothslugandidper entry, allowing correct interpolation of URL patterns using{slug},{id}, or both<changefreq>and<priority>(ignored by all major search engines)validateIdentifier()rulesTest coverage:
urlPatterninclusion,lastmodon collections,collectionSlugfiltering, and null slug handling🤖 Generated with Claude Code