import { Feed, type Item as FeedItem } from "feed"; import ogImage from "@/app/opengraph-image.jpg"; import authorConfig from "@/lib/config/author"; import siteConfig from "@/lib/config/site"; import { getPost, getFrontMatter } from "@/lib/posts"; /** * Returns a `Feed` object, which can then be processed with `feed.rss2()`, `feed.atom1()`, or `feed.json1()`. * @see https://github.com/jpmonette/feed#example */ export const buildFeed = (): Feed => { const frontmatter = getFrontMatter(); const feed = new Feed({ id: `${process.env.NEXT_PUBLIC_BASE_URL}`, link: `${process.env.NEXT_PUBLIC_BASE_URL}`, title: siteConfig.name, description: siteConfig.description, copyright: `https://spdx.org/licenses/${siteConfig.license}.html`, updated: frontmatter[0] ? new Date(frontmatter[0].date) : undefined, image: `${process.env.NEXT_PUBLIC_BASE_URL}${ogImage.src}`, feedLinks: { rss: `${process.env.NEXT_PUBLIC_BASE_URL}/feed.xml`, atom: `${process.env.NEXT_PUBLIC_BASE_URL}/feed.atom`, }, author: { name: authorConfig.name, link: process.env.NEXT_PUBLIC_BASE_URL, email: authorConfig.email, }, }); // parse posts into feed items const posts: FeedItem[] = frontmatter.map((post) => ({ guid: post.permalink, link: post.permalink, title: post.title, description: post.description, author: [ { name: authorConfig.name, link: `${process.env.NEXT_PUBLIC_BASE_URL}`, }, ], date: new Date(post.date), content: ` ${getPost(post.slug)?.feedHtml}
`.trim(), })); // sort posts reverse chronologically in case the promises resolved out of order posts.sort((post1, post2) => new Date(post2.date).getTime() - new Date(post1.date).getTime()); // officially add each post to the feed posts.forEach((post) => { feed.addItem(post); }); return feed; };