diff --git a/packages/website/package.json b/packages/website/package.json index 06d0682ba..6c083baa7 100644 --- a/packages/website/package.json +++ b/packages/website/package.json @@ -6,7 +6,7 @@ "private": true, "scripts": { "dev": "waku dev", - "build": "waku build", + "build": "VITE_EXPERIMENTAL_WAKU_ROUTER=true waku build", "start": "waku start" }, "dependencies": { diff --git a/packages/website/src/pages/api/rss.xml.ts b/packages/website/src/pages/api/rss.xml.ts new file mode 100644 index 000000000..b601503b7 --- /dev/null +++ b/packages/website/src/pages/api/rss.xml.ts @@ -0,0 +1,86 @@ +import { compileMDX } from 'next-mdx-remote/rsc'; +import { readdirSync, readFileSync } from 'node:fs'; + +type Item = { + title: string; + link: string; + description: string; + pubDate: string; +}; + +const generateRSSFeed = (items: Item[]) => { + const itemsXML = items + .map( + (item) => ` + + ${item.title} + ${item.link} + ${item.pubDate} + ${item.description} + ${item.link} + `, + ) + .join(''); + + return ` + + + + Waku + https://waku.gg + The minimal React framework + ${itemsXML} + +`; +}; + +export const GET = async () => { + const blogFileNames: Array = []; + readdirSync('./private/contents').forEach((fileName) => { + if (fileName.endsWith('.mdx')) { + blogFileNames.push(fileName); + } + }); + + const items: Item[] = []; + + for await (const fileName of blogFileNames) { + const path = `./private/contents/${fileName}`; + const source = readFileSync(path, 'utf8'); + const mdx = await compileMDX({ + source, + options: { parseFrontmatter: true }, + }); + + const frontmatter = mdx.frontmatter as { + title: string; + description: string; + slug: string; + date: string; + }; + const [year, month, day] = frontmatter.date.split('/').map(Number) as [ + number, + number, + number, + ]; + items.push({ + title: frontmatter.title, + link: `https://waku.gg/blog/${frontmatter.slug}`, + description: frontmatter.description || '', + pubDate: new Date(Date.UTC(year, month - 1, day)).toUTCString(), + }); + } + + const rssFeed = generateRSSFeed(items); + return new Response(rssFeed, { + headers: { + 'Content-Type': 'application/rss+xml', + }, + }); +}; + +export const getConfig = async () => { + return { + render: 'static', + } as const; +};