mirror of
https://github.com/supabase/supabase.git
synced 2026-10-08 19:05:06 +03:00
- Update Changelog [index page layout](https://zone-www-dot-com-git-feat-changelog-update-supabase.vercel.app/changelog): - with full timeline - filterable based on text search and tags - New Changelog [detail pages](https://zone-www-dot-com-git-feat-changelog-update-supabase.vercel.app/changelog/45071) - all added to www_sitemap - Changelog [RSS Feed](https://zone-www-dot-com-git-feat-changelog-update-supabase.vercel.app/changelog/45071) + llm-friendly [/changelog.md](https://zone-www-dot-com-git-feat-changelog-update-supabase.vercel.app/changelog.md) - and llm-friendly changelog detail md files: https://zone-www-dot-com-git-feat-changelog-update-supabase.vercel.app/changelog/45071.md ## Before <img width="1604" height="1094" alt="Screenshot 2026-04-27 at 17 07 55" src="https://github.com/user-attachments/assets/eac52f14-e447-4f64-8d50-a8e287ccf989" /> ## After <img width="1247" height="849" alt="changelog-index" src="https://github.com/user-attachments/assets/69b7bae1-63eb-4a4d-a065-7541ed9738b4" /> ### Detail page <img width="1695" height="1101" alt="Screenshot 2026-04-27 at 18 27 27" src="https://github.com/user-attachments/assets/accd4be8-d665-43ed-bcb7-0e6baf537762" /> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Release Notes * **New Features** * Redesigned changelog page with full-text search and product tag filtering * Individual pages for each changelog entry with dedicated URLs * Added RSS feeds for changelog updates and product-specific feeds * Copy changelog entries as markdown with one click * Direct sharing integration with ChatGPT and Claude <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
98 lines
3.4 KiB
TypeScript
98 lines
3.4 KiB
TypeScript
import authors from 'lib/authors.json'
|
|
|
|
const dayjs = require('dayjs')
|
|
var utc = require('dayjs/plugin/utc')
|
|
var advancedFormat = require('dayjs/plugin/advancedFormat')
|
|
dayjs.extend(utc)
|
|
dayjs.extend(advancedFormat)
|
|
|
|
export function xmlEncodeRss(str: string | undefined | null): string {
|
|
if (str === undefined || str === null) {
|
|
return ''
|
|
}
|
|
return str
|
|
.replace(/&/g, '&')
|
|
.replace(/</g, '<')
|
|
.replace(/>/g, '>')
|
|
.replace(/"/g, '"')
|
|
.replace(/'/g, ''')
|
|
}
|
|
|
|
const generateRssItem = (post: any): string => {
|
|
const encodedTitle = xmlEncodeRss(post.title)
|
|
const encodedPath = xmlEncodeRss(post.path)
|
|
const encodedDescription = xmlEncodeRss(post.description)
|
|
const formattedDate = dayjs(post.date)
|
|
.utcOffset(0, true)
|
|
.startOf('day')
|
|
.format('ddd, DD MMM YYYY HH:mm:ss [-0700]')
|
|
|
|
return `<item>
|
|
<guid>https://supabase.com${encodedPath}</guid>
|
|
<title>${encodedTitle}</title>
|
|
<link>https://supabase.com${encodedPath}</link>
|
|
<description>${encodedDescription}</description>
|
|
<pubDate>${formattedDate}</pubDate>
|
|
</item>
|
|
`
|
|
}
|
|
|
|
export type ChangelogRssItemInput = {
|
|
title: string
|
|
url: string
|
|
sortDate: string
|
|
}
|
|
|
|
/** Implemented in `./changelog-rss.mjs` (used by `scripts/generateStaticContent.mjs`). */
|
|
export { generateChangelogRssXml } from './changelog-rss.mjs'
|
|
|
|
// This utility generates RSS feeds for specialized content:
|
|
// 1. Customer stories RSS feed (customers-rss.xml) - used by pages/customers.tsx via getStaticProps
|
|
// 2. Author-specific PlanetPG RSS feeds (planetpg-{authorID}-rss.xml) - filtered feeds for individual authors
|
|
// 3. Changelog RSS (changelog-rss.xml) — built in generateStaticContent.mjs via ./changelog-rss.mjs
|
|
//
|
|
// Note: The main blog RSS feed (rss.xml) containing all blog posts is generated separately
|
|
// in generateStaticContent.mjs during the build process. This file is NOT used for the main blog feed.
|
|
//
|
|
// Usage:
|
|
// - Without authorID: Generates generic RSS feed (used for customer stories)
|
|
// - With authorID: Generates author-specific feed with custom title/description for PlanetPG authors
|
|
export const generateRss = (posts: any[], authorID?: string): string => {
|
|
const authorInfo = authors.find((item) => item.author_id === authorID)
|
|
|
|
const formattedDate = dayjs(posts[0].date)
|
|
.utcOffset(0, true)
|
|
.startOf('day')
|
|
.format('ddd, DD MMM YYYY HH:mm:ss [-0700]')
|
|
|
|
if (authorID) {
|
|
return `
|
|
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
|
|
<channel>
|
|
<title>'Postgres | Supabase Blog</title>
|
|
<link>https://supabase.com/blog</link>
|
|
<description>Latest Postgres news from ${authorInfo?.author} at Supabase</description>
|
|
<language>en</language>
|
|
<lastBuildDate>${formattedDate}</lastBuildDate>
|
|
<atom:link href="https://supabase.com/planetpg-${authorID}-rss.xml" rel="self" type="application/rss+xml"/>
|
|
${posts.map(generateRssItem).join('')}
|
|
</channel>
|
|
</rss>
|
|
`
|
|
} else {
|
|
return `
|
|
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
|
|
<channel>
|
|
<title>Blog - Supabase</title>
|
|
<link>https://supabase.com</link>
|
|
<description>Latest news from Supabase</description>
|
|
<language>en</language>
|
|
<lastBuildDate>${formattedDate}</lastBuildDate>
|
|
<atom:link href="https://supabase.com/rss.xml" rel="self" type="application/rss+xml"/>
|
|
${posts.map(generateRssItem).join('')}
|
|
</channel>
|
|
</rss>
|
|
`
|
|
}
|
|
}
|