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 -->
<!-- ccr-slack-attribution -->
_Requested by **Sean Oliver** · [Slack
thread](https://supabase.slack.com/archives/C07P3AU3J2D/p1787036390117589?thread_ts=1787036390.117589&cid=C07P3AU3J2D)_
## I have read the
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
file.
YES
## What kind of change does this PR introduce?
Chore. One entry added to the www sitemap generator.
## What is the current behavior?
`https://supabase.com/evals` is missing from `sitemap_www.xml`, so
search crawlers are never told the page exists. `robots.txt` doesn't
block it, they just have no way to find it from the sitemap.
The reason is that `/evals` is served by a separate Vercel project and
only reaches supabase.com through a proxy rewrite in
`apps/www/lib/rewrites.js`:
```js
{
source: '/evals',
destination: 'https://supabase-evals.vercel.app',
},
```
`apps/www/internals/generate-sitemap.mjs` builds its URL list by
globbing local route source files (`pages/**`, `_blog/*.mdx`,
prerendered `.next/server/pages/**`, etc.) and never resolves rewrites.
There is no page file behind `/evals`, so the globs can't discover it.
Closes GROWTH-1113.
## What is the new behavior?
`https://supabase.com/evals` appears once in the generated
`sitemap_www.xml`, with the same `<changefreq>weekly</changefreq>` and
`<priority>0.5</priority>` as every other entry in the file (no entry in
this sitemap carries a `<lastmod>`).
The entry is a small named const spread into the final `urlset` join,
next to `changelogDetailUrls` — the existing precedent in this file for
URLs with no page file behind them. Nothing else in the script changed,
and the sitemap index output (`sitemap.xml`) is byte-identical.
```diff
+ // /evals is a separate app proxied onto supabase.com via a rewrite in lib/rewrites.js,
+ // so it has no page file for the globs above to find. Hardcode it here.
+ const proxiedAppUrls = [
+ `
+ <url>
+ <loc>https://supabase.com/evals</loc>
+ <changefreq>weekly</changefreq>
+ <priority>0.5</priority>
+ </url>
+ `,
+ ]
+
const sitemap = `
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
- ${[...staticUrls, ...changelogDetailUrls].join('')}
+ ${[...staticUrls, ...changelogDetailUrls, ...proxiedAppUrls].join('')}
</urlset>
`
```
This only makes the URL discoverable. Whether the page content itself is
crawlable is separate work, tracked in the evals repo.
## Additional context
Verification, run locally against this branch. The generator runs
standalone (`node ./internals/generate-sitemap.mjs` from `apps/www`); a
missing `.next` just means the globs match fewer pages, and the missing
changelog RSS is caught internally.
I generated `sitemap_www.xml` from `master` and from this branch and
diffed the two. The added entry is the only difference:
```
3271a3272,3277
>
> <url>
> <loc>https://supabase.com/evals</loc>
> <changefreq>weekly</changefreq>
> <priority>0.5</priority>
> </url>
```
Exactly one occurrence, with its neighbouring entry for context:
```
$ grep -c '<loc>https://supabase.com/evals</loc>' public/sitemap_www.xml
1
<url>
<loc>https://supabase.com/terms</loc>
<changefreq>weekly</changefreq>
<priority>0.5</priority>
</url>
<url>
<loc>https://supabase.com/evals</loc>
<changefreq>weekly</changefreq>
<priority>0.5</priority>
</url>
</urlset>
```
Other checks:
- Both outputs parse as well-formed XML (Python `xml.dom.minidom`):
`sitemap_www.xml` has 545 `<url>` elements, `sitemap.xml` parses OK.
- `sitemap.xml` (the sitemap index) is identical to the pre-change
output; `diff` reports no changes.
- `npx prettier --check internals/generate-sitemap.mjs` → "All matched
files use Prettier code style!"
- Both generated sitemaps are gitignored (`apps/www/.gitignore` lines
29-30), confirmed with `git check-ignore`. `git status` shows only
`apps/www/internals/generate-sitemap.mjs`, so no generated file is in
the commit.
- No test, snapshot, or fixture anywhere in the repo references the
sitemap generator, so there was nothing to run. Its only caller is
`apps/www`'s `postbuild` script.
Not run: `pnpm --filter=www build`. It fails during "Collecting page
data" on a clean `master` checkout in this environment too, so the
failure is pre-existing and unrelated, and this change needs no build to
verify.
Co-authored-by: Claude <noreply@anthropic.com>
## Info architecture change around "Partners"
The www "integrations" now become more partner-driven.
`/partners/integrations` -> now Partner Catalog under
`/partners/catalog` (old links redirect to new paths)
Moved them close together in the nav dropdown and in the footer
<img width="494" height="336" alt="Screenshot 2026-07-09 at 11 06 41"
src="https://github.com/user-attachments/assets/a875fef0-0ab8-47ca-8756-d658b27c4892"
/>
<img width="1149" height="665" alt="Screenshot 2026-07-09 at 11 09 48"
src="https://github.com/user-attachments/assets/9631bb72-fe25-4fb4-b1af-9f14a37d02e7"
/>
## /partners
This page remains untouched in this PR, updates to layout, content and
intake form are delegated to #47874
## /partners/catalog
Listed in the
[catalog](https://zone-www-dot-com-git-feat-www-partners-pages-supabase.vercel.app/partners/catalog)
are now partners. Some partners match with a listing.
<img width="1207" height="866" alt="Screenshot 2026-07-09 at 11 14 17"
src="https://github.com/user-attachments/assets/b65216be-976f-4ef5-91f8-1ad49da87b45"
/>
## /partners/catalog/[partner]
Each partner can have one or more "listings" which are either
- simple guides
- foreign data wrappers
- dashboard integrations
Integrations available in the dashboard now all have a prominent
"Install integration" cta to open it in the dashboard [integrations
page](https://supabase.com/dashboard/project/_/integrations).
<img width="1269" height="776" alt="Screenshot 2026-07-09 at 11 16 51"
src="https://github.com/user-attachments/assets/3c7bb715-ffce-4d0a-905f-9a660c3b1f5a"
/>
## Docs
Update docs →
[Preview](https://docs-git-feat-www-partners-pages-supabase.vercel.app/docs/guides/integrations)
- remove "Supabase marketplace"
- use "Dashboard Integrations and Partner Catalog
- update integrations in sidenav to link to updated /partners/catalog/**
listings
<img width="1520" height="696" alt="Screenshot 2026-07-15 at 12 54 47"
src="https://github.com/user-attachments/assets/9f5a2794-4536-4299-97df-9732d3d75b4c"
/>
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Added a Partner Catalog experience with search, category filters,
official-partner toggle, responsive filtering (sidebar + bottom sheet),
grid/list views, and featured partners.
* Added Partner Catalog detail pages with tabbed listings, MDX-rendered
content, image gallery with zoom overlay, and “add/install” actions.
* **Improvements**
* Updated “Become a Partner” layout and form support for prefilled
values and checkbox-group fields (including validation).
* Updated navigation/footer/docs and partner tile links to use Partner
Catalog routes; expanded redirects from legacy integrations paths.
* Added public agent-skills discovery manifest.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Alan Daniel <stylesshjs@gmail.com>
Co-authored-by: Alex Hall <alex.hall@supabase.io>
Co-authored-by: Miranda Limonczenko <miranda.limonczenko@supabase.io>
## Summary
Google Search Console flagged 4 "URL not allowed" errors on
`sitemap_www.xml` — malformed URLs like
`https://supabase.comdata/legal/terms/v1` (missing slash, non-existent
path). The generator was globbing `data/**/*.mdx`, picking up the 4
content-source MDX files under `data/legal/` that are imported by
`pages/terms.tsx` and `pages/enterprise-terms.tsx` but are not
themselves routed. With no path replacement mapping `data/...` to a
route and no leading slash, the URL template concatenated to garbage.
The real `/terms` and `/enterprise-terms` URLs come from the
`pages/*.tsx` glob and are unaffected.
## Changes
- Remove `data/**/*.mdx` glob (and its companion `!data/*.mdx` exclude)
from the sitemap generator. `apps/www/data/` has no routed MDX, only
content sources imported into pages.
- Anchor the `pages` prefix replace: `.replace('pages', '')` →
`.replace(/^pages/, '')`. String-form replace is first-occurrence and
would mangle any future filename containing `pages` as a non-prefix
substring (e.g., `_blog/about-pages.mdx` → `/blog/about-`). No current
files trigger this; defensive hardening.
## Testing
Regenerated the sitemap locally and verified:
- [x] `grep -c "supabase.comdata" public/sitemap_www.xml` → `0` (was 4)
- [x] `<loc>https://supabase.com/terms</loc>` and
`<loc>https://supabase.com/enterprise-terms</loc>` still present
- [x] Every `<loc>` matches
`^<loc>https://supabase\.com(/[a-zA-Z0-9].*)?</loc>$` (no malformed URLs
of any kind)
- [x] Total loc count stable across both commits (regression-free for
the anchor change)
Local count is lower than prod (527 vs 906) because
`.next/server/pages/**` partner/expert/feature HTML globs only resolve
after a full build — runs correctly via `postbuild` on Vercel.
After deploy lands, resubmit `sitemap_www.xml` in Google Search Console
to force a re-crawl (otherwise daily-ish). Expect status to flip from "4
errors" to "Success" and Discovered pages: 906 → 902.
## Linear
- fixes GROWTH-837
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
## Release Notes
* **Chores**
* Improved sitemap generation to properly index specific content
sections (blog, case studies, customers, events, and alternatives) with
refined route path processing for better search engine discoverability.
[](https://app.coderabbit.ai/change-stack/supabase/supabase/pull/45775)
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
- change changelog.md formatting
- make changelog entries slugs more descriptive (eg
/changelog/123-new-change)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Refactor**
* Updated changelog entry URLs to use slug-based identifiers instead of
numeric IDs for improved readability and SEO-friendliness, with
automatic redirects for existing links.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This PR removes all CMS code from the `www` app. This includes fetching
of blog posts, API routes for proxying blog posts and types.
All functionality should remain the same (and the number of blog posts
should be the same).
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Chores**
* Removed CMS integration, APIs, preview/draft/revalidate endpoints,
related env vars and dependency; switched to static markdown-only blog
pipeline.
* **Refactor**
* Simplified image and author resolution, tightened component props to
static post shapes, and migrated imports to path aliases.
* **Documentation**
* Deleted CMS integration docs and rich-text conversion helpers.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
* Use the "eslint" command instead of built-in next lint since it's getting obsolete.
* Bump all deps to support eslint 9+.
* Convert the rules in eslint-config-supabase to be flat-config compatible.
* Migrate all apps to use the new eslint config rules.
* Fix all errors found in the new setup.
* Fix the no default exports ignores.
* Scan all files for linting in studio.
* Fix all lint errors.
* Make the reportUnusedDisableDirectives a warning.
* show cms blog posts in www
* remove contentlayer from www
* outputFileTracingExcludes
* update remotePatterns
* fetch cms posts server-side with revalidation
* add cms env vars to turbo.json
* add www env vars to turbo.json
* include cms posts in www sitemap
* add migration to remove image from cms post
* update cms meta image mapping in www
* Consolidate different versions of postcss. Remove @mertasan/tailwindcss-variables from ui package.
* Bump vitest in pg-meta to remove a vulnerable version of vite.
* Bump dompurify.
* Bump all octokit deps to solve 2 vulns.
* Fix warnings about destructuring json imports.
* Remove a console.log in docs.
* Fix the changelog page to use an ESM import.
* Stabilize the generate-sitemap script output.
* Try another fix for the changelog.
* init features page
* fix filtering
* seo boostg
* add features to sitemap
* update copywriting
* improve features descriptions
* more studio features
* moar featuress
* better back to features
* prev next feature nav
* clean
* improve page footer
* fixes
* stuff
* sync filters with query params on page load
* better mobile layout
* 16px mobile input fontsize
* add cover images or videos to features
* improve a11y
* update sitemap
* last changes
* update schema definitions
* Empty commit.
* Another empty commit.
* Remove a postbuild command.
* Empty commit to trigger www caching.
* Organize the www tasks into turbo.
* Revert "Empty commit to trigger www caching."
This reverts commit d9c1c66c7f.
* Revert all changes but add caching for the www#build.
* Random change.
* Revert "Random change."
This reverts commit c925da9046.
* Remove unneeded script.