Changelog entry pages advertised a `.md` alternate tag unconditionally
while the page is ISR, so an entry published in the changelog repo
between www deploys pointed agents at a `.md` sibling that 404s until
the next build (the static file and `CHANGELOG_PAGES` are both
build-time artifacts). PR #49357 made bare-URL negotiation fail closed
for those entries; I gate the advertising side here the same way.
**Changed:**
- **No more dead `.md` links on freshly published entries**:
`getStaticProps` passes a `hasMarkdownVariant` flag computed from
`CHANGELOG_PAGES` membership and the page renders the alternate tag only
when true. An entry published between deploys carries no tag until the
build that ships its `.md` file; the set reference stays inside
`getStaticProps`, so the generated module stays out of the client
bundle.
- **Drift coverage**: `md-alternates.test.ts` gains the changelog
direction, source-level like the existing `_app.tsx` drift test; the
assertion pins the full `CHANGELOG_PAGES.has(` +
backtick-`changelog/${entry.slug}`-backtick + `)` expression so a
dropped key prefix fails the suite, and removing the gate fails it too.
**Note:** without changelog sync secrets `CHANGELOG_PAGES` is empty, so
the tag never renders in local dev. Preview and prod are the
verification surface.
## To test
Tested on Vercel preview:
- [x] Open a published changelog entry page and view source: expect
`<link rel="alternate" type="text/markdown"
href="/changelog/<slug>.md">` in the head — observed exact href
`/changelog/19669-supavisor-1-0.md`
- [x] Fetch that href: expect 200 with `content-type: text/markdown` —
observed 200, `text/markdown; charset=utf-8`
- [x] (added) Client-side nav from `/changelog` into an entry: alternate
tag appears with that entry's slug; hopping to a second entry updates
the href (no stale tag)
- [x] (added) Navigating back to `/changelog`: entry tag gone; the index
shows its own pre-existing `/changelog.md` alternate (hardcoded in
`pages/changelog.tsx`, outside this diff), and `/changelog.md` returns
200 `text/markdown`
- [x] (added) Console: zero new errors across all scenarios vs page-load
baseline
## Linear
- fixes GROWTH-1120
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Changelog pages now advertise a Markdown alternate link only when a
Markdown version is available.
* Prevented links to unavailable Markdown content from appearing on
changelog entries.
* **Tests**
* Added coverage to verify correct Markdown alternate detection and
rendering.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## 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?
Security/bug fix
## What is the current behavior?
The changelog entry parser exposes all YAML frontmatter fields parsed by
`matter()` directly to the client via Next.js props. This includes
private fields like `internal:` (escalation teams, notes) and
`reviewers:`, which get serialized into the page's `__NEXT_DATA__` and
are visible in View Source even if never rendered.
## What is the new behavior?
- Added `PUBLIC_FRONTMATTER_KEYS` constant that explicitly allowlists
only the fields safe to expose to the browser
- Added `toPublicFrontmatter()` function that filters frontmatter down
to the allowlist, dropping `internal:`, `reviewers:`, and any other
private keys
- Updated `parseChangelogEntryFile()` to apply the allowlist before
returning frontmatter to callers
- Added comprehensive unit tests covering both the filtering logic and
the integration with the parser
This uses an allowlist approach rather than a denylist, so new private
fields added upstream won't silently leak to clients.
## Additional context
The allowlist is kept in sync with `ChangelogEntryFrontmatter` in
`changelog-repo.ts` per the code comment. Tests verify that:
- Only allowlisted keys are present in the returned frontmatter
- Private fields like `internal` and `reviewers` are never exposed
- Public fields flow through untouched
- Undefined values are omitted from the result
https://claude.ai/code/session_017uSmnCLsskFYR7YH8DKGkr
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Added a shared changelog title renderer that safely displays titles as
inline Markdown.
* Added plain-text title extraction for consistent headings and SEO
metadata.
* **Bug Fixes**
* Prevented private/internal changelog frontmatter (including reviewer
metadata) from being exposed to browser-rendered pages.
* Ensured featured and non-featured changelog timelines stay consistent
even when some entries fail to serialize.
* Improved the changelog detail not-found behavior to revalidate instead
of caching 404s indefinitely.
* **Tests**
* Added coverage for public frontmatter allowlisting, date normalization
(`publish_date`/sorting), and `sortDate` consistency across YAML
variations.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Lukas Bernert <lukas@bernert.at>
## What kind of change does this PR introduce?
Sync changelog from private supabase/changelog.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Changelog entries now come from the structured changelog repository.
* Added filters for change type, product stage, and self-hosted impact.
* Updated badge UI for affected products and change types with filter
links.
* Changelog detail sidebar now shows lifecycle stage, sunset dates, and
self-hosted impact (when available).
* **Improvements**
* Product category discovery and filtering now use affected products.
* Discussion links show only when legacy discussion data is present.
* RSS feeds and generated changelog markdown now use the updated
metadata.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Problem
We want to upgrade to react 19. However some libraries aren't compatible
with it. Besides, `next-mdx-remote` is now archived and not maintained
anymore.
## Solution
The [NextJS
documentation)[https://nextjs.org/docs/15/app/guides/mdx#remote-mdx]
suggest using
[`next-mdx-remote-client`](https://github.com/ipikuka/next-mdx-remote-client)
which was a fork of `next-mdx-remote`.
- [x] migrate `apps/www` from `next-mdx-remote` to
`next-mdx-remote-client`
- [x] migrate `apps/www` from `next-mdx-remote` to
`next-mdx-remote-client`
I haven't noticed any change in the pages.
When upgrading to react 19, we'll have to use v2 of
`next-mdx-remote-client`.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Refactor**
* Switched MDX rendering/serialization to a newer client-focused
implementation across docs and site for improved compatibility.
* **Bug Fixes**
* Improved handling of serialization errors so MDX failures render clear
fallback messages instead of breaking pages.
* **Chores**
* Updated local environment template value for the public anonymous key.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This PR migrates the whole monorepo to use Tailwind v4:
- Removed `@tailwindcss/container-queries` plugin since it's included by
default in v4,
- Bump all instances of Tailwind to v4. Made minimal changes to the
shared config to remove non-supported features (`alpha` mentions),
- Migrate all apps to be compatible with v4 configs,
- Fix the `typography.css` import in 3 apps,
- Add missing rules which were included by default in v3,
- Run `pnpm dlx @tailwindcss/upgrade` on all apps, which renames a lot
of classes
- Rename all misnamed classes according to
https://tailwindcss.com/docs/upgrade-guide#renamed-utilities in all
apps.
---------
Co-authored-by: Jordi Enric <jordi.err@gmail.com>
- 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 -->