How to add an RSS feed to your SvelteKit app May 7, 2024
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
.
Create a +server.ts
file inside src/routes/rss.xml
directory.
In +server.ts
file, export an async function named GET
. This will expose an endpoint that responds with the rss.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" ,
},
});
}