I added static App Router pages to the www sitemap, including the
homepage, pricing, and product pages. The generator previously scanned
only Pages Router and content files; it now strips route groups,
excludes dynamic segments, and emits these URLs without lastmod.
**Note:** The pre-existing Pages Router `/opt-out/[ref]` entry remains
outside this change.
## To test
Tested on the [www
preview](https://zone-www-dot-com-git-pamela-growth-1214-app-rou-1d4879-supabase.vercel.app/sitemap_www.xml):
- [x] Open `/sitemap_www.xml`: expect the homepage, `/pricing`, and
product routes once each, without route-group names or lastmod on those
entries.
- [x] Compare the sitemap's changelog URLs with `/changelog-rss.xml`:
expect every RSS item link to remain included, including text-slug
entries.
- [x] Open `/sitemap.xml`: expect the existing www and docs sitemap
links.
## Linear
- fixes GROWTH-1214
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
- **New Features**
- Sitemap generation now includes static pages built with the Next.js
App Router.
- Route groups are correctly omitted from generated URLs.
- Dynamic App Router routes are excluded from the sitemap.
- **Bug Fixes**
- Improved sitemap coverage and URL accuracy for applications using both
App Router and Pages Router pages.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
The www sitemap generator reads changelog URLs from the build-generated
RSS feed but only accepted links whose slug starts with a number, the
shape `computeChangelogEntrySlug` produces solely for entries carrying
`legacy_gh_discussion`. Every changelog entry authored since that
migration has a plain text slug and was silently missing from
`sitemap_www.xml`. I widened the link match to any non-empty slug; the
RSS builder is the only producer of that file and emits exactly one link
per item, so no other filter is needed.
I added a text-slug RSS item to the fixture-driven sitemap test and
asserted that the changelog URL list equals the RSS item list, so a
future filter that drops entries fails the suite.
**Note:** text-slug entries now pass through the same fail-the-build
pubDate check that numeric-prefixed entries already did after #50198. A
changelog entry with no `publish_date` and no date-prefixed filename
would produce an unparseable pubDate and stop the www build. The
alternative, shipping the URL without lastmod, is a one-line change. I
kept the gate because every current changelog entry carries a
date-prefixed filename, the changelog repo documents that convention,
and the build error names the entry URL.
## To test
Tested on Vercel preview:
- [x] Count `<item>` blocks in `<preview>/changelog-rss.xml`, then count
`/changelog/` locs in `<preview>/sitemap_www.xml`, expect the two counts
to match
- [x] Search the preview sitemap for `/changelog/pipelines`, expect one
`<loc>` entry with a `<lastmod>` date
- [x] Search the preview sitemap for a numeric-prefixed entry such as
`/changelog/47796-developer-update-july-2026`, expect it still present
## Linear
- fixes GROWTH-1212
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
- **Bug Fixes**
- Changelog pages with text-based slugs are now correctly recognized in
the sitemap.
- Sitemap entries for these changelog pages now use their RSS
publication dates.
- RSS links are matched more reliably, ensuring all valid changelog URLs
are included.
- Invalid publication dates are rejected instead of producing incorrect
sitemap metadata.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
I added content dates to `sitemap_www.xml` and `dateModified` to blog
JSON-LD so crawlers can compare freshness with page metadata. Both use
`updated` when present, otherwise the publication date.
**Changed:**
- **Consistent dates:** I use the same frontmatter parser for the blog
page and sitemap. It preserves authored dates across quoting and
timezones and rejects JavaScript frontmatter.
- **Invalid dates stop the build:** I reject impossible calendar days,
out-of-range times and offsets, malformed dates, and `updated` before
publication. Content changes run the generator in CI.
- **Authoring:** I documented optional `updated` for substantive
revisions. Events, static pages, and `/evals` omit `<lastmod>`.
**Note:** Changelog dates come from RSS. Existing sitemap omissions for
nonnumeric changelog slugs (GROWTH-1212) and app-router pages
(GROWTH-1214) remain separate.
## To test
On the preview:
- [x] Open `/sitemap_www.xml`: blog, alternatives, customer stories, and
included changelog entries should carry `YYYY-MM-DD` lastmod values.
Verified on the 2092513 preview: all 425 blog, 3 alternatives, 43
customer story, and 207 changelog entries carry a `YYYY-MM-DD` lastmod,
zero malformed values. Production currently emits no lastmod at all.
- [x] Inspect `/blog/supabase-is-now-available-in-gemini-enterprise`:
BlogPosting `dateModified` should be `2026-09-09`, matching its sitemap
entry. Verified: one BlogPosting block, `datePublished` and
`dateModified` both `2026-09-09`, sitemap lastmod `2026-09-09`.
- [x] Find the `/company` and event entries in the sitemap: neither
should carry lastmod. Verified: `/company` and all 13 `/events/` entries
have no lastmod.
- [x] Added: `/evals` and the `/changelog` index carry no lastmod
either.
- [x] Added: the blog page renders with no new console errors. The only
console error is a `/docs?_rsc=` prefetch 404: the preview host serves
404 for `/docs` itself, unrelated to this change.
## Linear
- fixes GROWTH-1206
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
- **New Features**
- Blog posts now support optional updated dates for substantive
revisions.
- Sitemap entries include accurate modification dates for blog,
alternatives, customers, and changelog content.
- Blog structured data now includes the post’s modification date.
- **Bug Fixes**
- Improved validation prevents invalid or inconsistent content dates
from generating incorrect sitemap data.
- Changelog sitemap links are deduplicated and assigned their published
dates.
- **Documentation**
- Added guidance for specifying publication and update dates in blog
post metadata.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->