Skip to content

Commit 021d241

Browse files
committed
Add prerendered endpoint for each feed type
1 parent 034ffd6 commit 021d241

File tree

5 files changed

+85
-0
lines changed

5 files changed

+85
-0
lines changed

nuxt.config.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,9 @@ export default defineNuxtConfig({
192192
'/recharging': { prerender: true },
193193
'/pds': { isr: 86400 }, // revalidate daily
194194
'/blog/**': { prerender: true },
195+
'/rss.xml': { prerender: true },
196+
'/atom.xml': { prerender: true },
197+
'/feed.json': { prerender: true },
195198
// proxy for insights
196199
'/_v/script.js': {
197200
proxy: 'https://npmx.dev/_vercel/insights/script.js',

server/routes/atom.xml.get.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { getFeed } from '../utils/feeds'
2+
3+
export default defineEventHandler(event => {
4+
setHeader(event, 'Content-Type', 'application/atom+xml')
5+
setHeader(event, 'Access-Control-Allow-Origin', '*')
6+
7+
const atomFeed = getFeed().atom1()
8+
9+
return atomFeed
10+
})

server/routes/feed.json.get.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { getFeed } from '../utils/feeds'
2+
3+
export default defineEventHandler(event => {
4+
setHeader(event, 'Content-Type', 'application/feed+json')
5+
setHeader(event, 'Access-Control-Allow-Origin', '*')
6+
7+
const jsonFeed = getFeed().json1()
8+
9+
return jsonFeed
10+
})

server/routes/rss.xml.get.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { getFeed } from '../utils/feeds'
2+
3+
export default defineEventHandler(event => {
4+
setHeader(event, 'Content-Type', 'application/rss+xml')
5+
setHeader(event, 'Access-Control-Allow-Origin', '*')
6+
7+
const rssFeed = getFeed().rss2()
8+
9+
return rssFeed
10+
})

server/utils/feeds.ts

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import { Feed } from 'feed'
2+
import { posts } from '#blog/posts'
3+
4+
export const rssPath = '/rss.xml'
5+
export const atomPath = '/atom.xml'
6+
export const jsonPath = '/feed.json'
7+
8+
let feed: Feed | undefined = undefined
9+
10+
export function getFeed(): Feed {
11+
if (!feed) {
12+
feed = generateFeed()
13+
}
14+
return feed
15+
}
16+
17+
function generateFeed(): Feed {
18+
// Generate content for RSS, Atom and JSON feeds
19+
const feed = new Feed({
20+
title: 'Blog - npmx',
21+
description: 'a fast, modern browser for the npm registry',
22+
id: 'https://npmx.dev/',
23+
link: 'https://npmx.dev/',
24+
language: 'en',
25+
image: 'https://npmx.dev/logo.svg',
26+
favicon: 'https://npmx.dev/favicon.ico',
27+
feedLinks: {
28+
rss: new URL(rssPath, 'https://npmx.dev').toString(),
29+
atom: new URL(atomPath, 'https://npmx.dev').toString(),
30+
json: new URL(jsonPath, 'https://npmx.dev').toString(),
31+
},
32+
})
33+
34+
for (const post of posts.filter(post => !post.draft)) {
35+
feed.addItem({
36+
title: post.title,
37+
id: new URL(post.path, 'https://npmx.dev').toString(),
38+
link: new URL(post.path, 'https://npmx.dev').toString(),
39+
description: post.description,
40+
author: post.authors.map(author => ({
41+
name: author.name,
42+
link: author.profileUrl ?? undefined,
43+
// author.avatar is a relative URL - make it absolute to work in feed readers
44+
avatar: author.avatar ? new URL(author.avatar, 'https://npmx.dev').toString() : undefined,
45+
})),
46+
date: new Date(post.date),
47+
image: post.image,
48+
})
49+
}
50+
51+
return feed
52+
}

0 commit comments

Comments
 (0)