my avatar Bahaa Zidan

How to add an RSS feed to your SvelteKit app

How to add an RSS feed to your SvelteKit app hero image
  1. Install the Feed npm package to your project.
npm i feed
  1. Create a directory (folder) named rss.xml in your routes directory.

    • The name doesn't matter. As long is it ends with .xml.
  2. Create a +server.ts file inside src/routes/rss.xml directory.

  3. 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() {
	// ...
}
  1. 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,
	});
}
  1. 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';
  1. 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),
		});
	}
}
  1. 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',
		},
	});
}