How to add an RSS feed to your SvelteKit app
Written by Bahaa Zidan
- 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 { getArticles } from "$lib";
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,
});
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",
},
});
}