Skip to content

Commit 511c82b

Browse files
committed
feat(blog): rss feed
1 parent ba06a6c commit 511c82b

3 files changed

Lines changed: 80 additions & 0 deletions

File tree

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
"@types/mdx": "^2.0.13",
2525
"class-variance-authority": "^0.7.1",
2626
"clsx": "^2.1.1",
27+
"feed": "^5.2.0",
2728
"gray-matter": "^4.0.3",
2829
"lucide-react": "^0.523.0",
2930
"next": "15.1.11",

pnpm-lock.yaml

Lines changed: 25 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/app/blog/rss/route.ts

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import { Feed } from "feed";
2+
import { posts } from "@/utils/posts";
3+
4+
export const dynamic = "force-static";
5+
6+
export async function GET() {
7+
const allPosts = posts.getPosts();
8+
const latestPost = allPosts[0];
9+
const siteUrl = process.env.NEXT_PUBLIC_BASE_URL || "https://jacobmoy.com";
10+
const author = {
11+
name: "Jacob Moy",
12+
email: "me@jacobmoy.com",
13+
link: siteUrl,
14+
};
15+
16+
const feed = new Feed({
17+
title: "Jacob Moy | Blog",
18+
description: "Jacob Moy's personal blog about software development, technology, and life.",
19+
id: siteUrl,
20+
link: siteUrl,
21+
language: "en",
22+
image: `${siteUrl}/favicon.ico`,
23+
favicon: `${siteUrl}/favicon.ico`,
24+
copyright: `All rights reserved ${new Date().getFullYear()}, Jacob Moy`,
25+
updated: latestPost ? new Date(latestPost.date) : new Date(),
26+
generator: "Feed for Node.js",
27+
feedLinks: {
28+
rss2: `${siteUrl}/blog/rss`,
29+
},
30+
author: author,
31+
});
32+
33+
allPosts.forEach((post) => {
34+
const url = `${siteUrl}/blog/posts/${post.slug}`;
35+
feed.addItem({
36+
title: post.title,
37+
id: url,
38+
link: url,
39+
description: post.description,
40+
content: post.content,
41+
author: [author],
42+
contributor: [author],
43+
date: new Date(post.date),
44+
image: post.image ? `${siteUrl}${post.image}` : undefined,
45+
});
46+
});
47+
48+
return new Response(feed.rss2(), {
49+
headers: {
50+
"Content-Type": "application/xml",
51+
"Cache-Control": "s-maxage=3600, stale-while-revalidate",
52+
},
53+
});
54+
}

0 commit comments

Comments
 (0)