mirror of
https://github.com/supabase/supabase.git
synced 2026-10-05 01:15:03 +03:00
fix(www): gate changelog md alternate on slug set (#49754)
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 -->
This commit is contained in:
1 parent
9d5c19e580
commit
8aade77966
2 files changed
+35
-4
No files matched your search
@@ -91,6 +91,25 @@ describe('markdown alternate drift', () => {
|
||||
).toBe(true)
|
||||
})
|
||||
|
||||
it('changelog entry page gates its .md alternate on CHANGELOG_PAGES membership', async () => {
|
||||
const source = await fs.readFile(
|
||||
path.join(process.cwd(), 'pages', 'changelog', '[slug].tsx'),
|
||||
'utf-8'
|
||||
)
|
||||
expect(
|
||||
source.includes('CHANGELOG_PAGES.has(`changelog/${entry.slug}`)'),
|
||||
'pages/changelog/[slug].tsx must compute the markdown alternate flag from CHANGELOG_PAGES membership using the changelog/-prefixed key the generator emits'
|
||||
).toBe(true)
|
||||
expect(
|
||||
source.includes('hasMarkdownVariant &&'),
|
||||
'pages/changelog/[slug].tsx must render the markdown alternate link only when hasMarkdownVariant is true'
|
||||
).toBe(true)
|
||||
expect(
|
||||
source.includes('rel="alternate" type="text/markdown"'),
|
||||
'pages/changelog/[slug].tsx must advertise the text/markdown alternate for published slugs'
|
||||
).toBe(true)
|
||||
})
|
||||
|
||||
it.for(MDX_SECTIONS)('%s pages advertise their .md sibling', async (urlPrefix) => {
|
||||
const appPagePath = path.join(process.cwd(), 'app', urlPrefix, '[slug]', 'page.tsx')
|
||||
if (!existsSync(appPagePath)) {
|
||||
|
||||
@@ -5,6 +5,7 @@ import { NextSeo } from 'next-seo'
|
||||
import Head from 'next/head'
|
||||
import Link from 'next/link'
|
||||
|
||||
import { CHANGELOG_PAGES } from '@/app/api-v2/md/content.generated'
|
||||
import { ChangelogDetailSidebar } from '@/components/Changelog/ChangelogDetailSidebar'
|
||||
import { ChangelogInlineMarkdown } from '@/components/Changelog/ChangelogInlineMarkdown'
|
||||
import CTABanner from '@/components/CTABanner'
|
||||
@@ -20,15 +21,25 @@ type PageProps = {
|
||||
slug: string
|
||||
frontmatter: ChangelogEntryFrontmatter
|
||||
source: MDXRemoteSerializeResult
|
||||
hasMarkdownVariant: boolean
|
||||
}
|
||||
|
||||
const ChangelogDetailPage = ({ title, created_at, slug, frontmatter, source }: PageProps) => {
|
||||
const ChangelogDetailPage = ({
|
||||
title,
|
||||
created_at,
|
||||
slug,
|
||||
frontmatter,
|
||||
source,
|
||||
hasMarkdownVariant,
|
||||
}: PageProps) => {
|
||||
const plainTitle = stripTitleMarkdown(title)
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<link rel="alternate" type="text/markdown" href={`/changelog/${slug}.md`} />
|
||||
</Head>
|
||||
{hasMarkdownVariant && (
|
||||
<Head>
|
||||
<link rel="alternate" type="text/markdown" href={`/changelog/${slug}.md`} />
|
||||
</Head>
|
||||
)}
|
||||
<NextSeo
|
||||
title={`${plainTitle} · Changelog`}
|
||||
description={plainTitle}
|
||||
@@ -106,6 +117,7 @@ export const getStaticProps: GetStaticProps<PageProps> = async ({ params }) => {
|
||||
slug: entry.slug,
|
||||
frontmatter: entry.frontmatter,
|
||||
source,
|
||||
hasMarkdownVariant: CHANGELOG_PAGES.has(`changelog/${entry.slug}`),
|
||||
},
|
||||
revalidate: 900,
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user