How to add an RSS feed to your SvelteKit app

- Install the Feed npm package to your project.
npm i feed
-
Create a directory (folder) named
rss.xml
in your routes directory.- The name doesn't matter. As long is it ends with
.xml
.
- The name doesn't matter. As long is it ends with
-
Create a
+server.ts
file insidesrc/routes/rss.xml
directory. -
In
+server.ts
file, export an async function namedGET
. This will expose an endpoint that responds with therss.xml
file.
export async function GET() {
// ...
}
- Create a
Feed
instance. I think most of these properties are self explanatory.
import { Feed } from 'feed';
export async function GET() {
const feed = new Feed({
title: 'Gebna blog',
description: "Gebna, GebnaTorky, or Bahaa Zidan's Blog",
id: 'https://gebna.gg/',
link: 'https://gebna.gg/',
language: 'en', // optional, used only in RSS 2.0, possible values: http://www.w3.org/TR/REC-html40/struct/dirlang.html#langcodes
favicon: 'https://gebna.gg/favicon.ico',
copyright: `Copyright ${new Date().getFullYear().toString()}, Bahaa Zidan / Gebna`,
generator: '🍉', // optional, default = 'Feed for Node.js'
feedLinks: {
rss: 'https://gebna.gg/rss.xml',
},
author: {
name: 'Gebna / Bahaa Zidan',
email: '[email protected]',
link: 'https://gebna.gg/whoami',
},
ttl: 60,
});
}
- Get the array of posts, articles, videos, or whatever you want to list in your feed. Here I implemented a
getArticles
function that returns an array of articles.
import { getArticles } from '$lib';
- Loop over the array of articles, add each article to the feed.
// ...
export async function GET() {
// ...
const articles = getArticles();
for (const article of articles) {
feed.addItem({
title: article.title,
description: article.description,
content: `<p>${article.description}</p> <div style="margin-top: 50px; font-style: italic;"> <strong><a href="https://gebna.gg${article.path}">Keep reading</a>.</strong> </div> <br /> <br />`,
link: `https://gebna.gg${article.path}`,
author: [
{
name: 'Gebna / Bahaa Zidan',
email: '[email protected]',
link: 'https://gebna.gg/whoami',
},
],
date: new Date(article.publishDate),
});
}
}
- Finally, return a response with body
feed.rss2()
. Don't forget the content type.
return new Response(feed.rss2(), {
headers: {
'Content-Type': 'application/xml; charset=utf-8',
},
});
Here's the full src/routes/rss.xml/+server.ts
file:
import { Feed } from 'feed';
import { getArticles } from '$lib';
export async function GET() {
const feed = new Feed({
title: 'Gebna blog',
description: "Gebna, GebnaTorky, or Bahaa Zidan's Blog",
id: 'https://gebna.gg/',
link: 'https://gebna.gg/',
language: 'en', // optional, used only in RSS 2.0, possible values: http://www.w3.org/TR/REC-html40/struct/dirlang.html#langcodes
favicon: 'https://gebna.gg/favicon.ico',
copyright: `Copyright ${new Date().getFullYear().toString()}, Bahaa Zidan / Gebna`,
generator: '🍉', // optional, default = 'Feed for Node.js'
feedLinks: {
rss: 'https://gebna.gg/rss.xml',
},
author: {
name: 'Gebna / Bahaa Zidan',
email: '[email protected]',
link: 'https://gebna.gg/whoami',
},
ttl: 60,
});
const articles = getArticles();
for (const article of articles) {
feed.addItem({
title: article.title,
description: article.description,
content: `<p>${article.description}</p> <div style="margin-top: 50px; font-style: italic;"> <strong><a href="https://gebna.gg${article.path}">Keep reading</a>.</strong> </div> <br /> <br />`,
link: `https://gebna.gg${article.path}`,
author: [
{
name: 'Gebna / Bahaa Zidan',
email: '[email protected]',
link: 'https://gebna.gg/whoami',
},
],
date: new Date(article.publishDate),
});
}
return new Response(feed.rss2(), {
headers: {
'Content-Type': 'application/xml; charset=utf-8',
},
});
}
Share