Skip to content

Commit 1afce30

Browse files
committed
Add RSS feed link to header and implement RSS XML generation
1 parent 412668b commit 1afce30

File tree

3 files changed

+41
-0
lines changed

3 files changed

+41
-0
lines changed

src/components/Header.astro

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,12 @@ import { Icon } from 'astro-icon/components'
2222
<li class="menu-item">
2323
<a href="/about">About</a>
2424
</li>
25+
<li class="menu-item type-icon animate-rotate">
26+
<a href="/blog/rss.xml" aria-label="Subscribe to RSS">
27+
<Icon name="lucide:rss" />
28+
<span class="sr-only">Subscribe to the RSS feed</span>
29+
</a>
30+
</li>
2531
<li class="menu-item type-icon animate-rotate">
2632
<a href="https://www.reddit.com/r/QuickDungeonCrawler/">
2733
<Icon name="fa-brands:reddit" />

src/layouts/DefaultLayout.astro

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ const {
2222

2323
<!-- favicon -->
2424
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
25+
<link rel="alternate" type="application/rss+xml" title="Quick Dungeon Crawler Blog RSS" href="/blog/rss.xml" />
2526

2627
<SiteMeta title={title} description={description.substring(0, 100)} url={url} image={image} author={author} />
2728
</head>

src/pages/blog/rss.xml.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { getCollection } from 'astro:content'
2+
3+
export async function GET({ site }) {
4+
const posts = await getCollection('blog')
5+
6+
posts.sort((a, b) => {
7+
const aDate = a.data.date ? new Date(a.data.date).getTime() : 0
8+
const bDate = b.data.date ? new Date(b.data.date).getTime() : 0
9+
return bDate - aDate
10+
})
11+
12+
const channelTitle = 'Quick Dungeon Crawler Blog'
13+
const channelLink = new URL('/blog', site).toString()
14+
const channelDescription = 'Official updates and patch notes for Quick Dungeon Crawler.'
15+
16+
const itemsXml = posts
17+
.map((post) => {
18+
const link = new URL(`/blog/${post.id}`, site).toString()
19+
const pubDate = post.data.date ? new Date(post.data.date).toUTCString() : new Date().toUTCString()
20+
21+
return `\n <item>\n <title><![CDATA[${post.data.title}]]></title>\n <link>${link}</link>\n <guid>${link}</guid>\n <description><![CDATA[${post.data.description}]]></description>\n <author><![CDATA[${post.data.author}]]></author>\n <pubDate>${pubDate}</pubDate>\n </item>`
22+
})
23+
.join('')
24+
25+
const rss = `<?xml version="1.0" encoding="UTF-8"?>\n<rss version="2.0">\n <channel>\n <title><![CDATA[${channelTitle}]]></title>\n <link>${channelLink}</link>\n <description><![CDATA[${channelDescription}]]></description>\n <lastBuildDate>${new Date().toUTCString()}</lastBuildDate>${itemsXml}\n </channel>\n</rss>`
26+
27+
return new Response(rss, {
28+
headers: {
29+
'Content-Type': 'application/rss+xml; charset=utf-8',
30+
'Cache-Control': 'public, max-age=0, s-maxage=600',
31+
},
32+
})
33+
}
34+

0 commit comments

Comments
 (0)