Last modified on

Generate RSS Feed with SvelteKit

RSS Feeds let readers know about new content on your website. SvelteKit provides endpoints that can be used to generate RSS feeds.

Recently I decided to list my most recent articles on my Github Profile README. I found a Github Action that does that from a RSS Feed. This led me to generate a RSS Feed for my blog, which is built with SvelteKit.

permalinkWhat is a RSS Feed?

For my generation, RSS Feed is something we heard about, but that we rarely used. I was curious to see how it works, and how it can be used.

RSS stands for Rich Site Summary. This is a format that has been standardized at the beginning of the 2000’s. RSS feeds are XML files. The XML file is a list of items, each item is a post, an article, anything that users might want to subscribe to, with a publication date, an author, a description, a link, etc.

Users use news aggregators, also called RSS readers, to read RSS feeds. They enter the URI of the feed, and the aggregator will fetch the feed periodically and display news. Users can subscribe to quality feeds they are interested in. Much more different paradigm than keeping scrolling on Twitter!

Other standards have been developed to serve the same purpose, such as Atom. This is the format that I chose for my RSS Feed, which actually is an Atom Feed.

permalinkGenerate the feed with SvelteKit

I did not want to generate the feed by concatenating strings, so I searched a library that does it for me and I found feed. With a nice TypeScript API, you can generate a RSS Feed, an Atom Feed or a JSON Feed.

SvelteKit has the concept of file-based routing. Routes are declared in src/routes directory. Pages are declared in a +page.svelte file, and colocated with files that do data fetching for this page, either called +page.ts or +page.server.ts, where +page.server.ts only runs on the server, while +page.ts runs on the browser and on the server (but should not depend on sensitive credentials, like a private API key, otherwise you need to run it only on the server).

SvelteKit also allows creating endpoints, that is, HTTP endpoints that can do anything, like responding to a PUT request, or sending a JSON file or an image computed at runtime.

I created src/routes/feed.xml/+server.ts file with the following code:

ts
import type { RequestHandler } from './$types';
import { Feed } from 'feed';
import { APP_URL } from '$lib/env';
import { getBlogPosts } from '../writing/_api';
import { urlcat } from '$lib/url';
// To also prerender this *page*, as SvelteKit treats it as a page regarding prerendering.
export const prerender = true;
// This function will be called when SvelteKit server
// receives a GET request for `/feed.xml`.
export const GET: RequestHandler = ({ setHeaders }) => {
// We get the list of all the blog posts.
// The list is ordered by publication date. The most recent post is at the top.
const blogPosts = getBlogPosts();
// We create the feed, with author's information.
const feed = new Feed({
title: 'Baptiste Devessier',
description: "Baptiste Devessier's blog",
id: APP_URL, // The id is used by RSS readers to identify the feed.
link: APP_URL,
language: 'en',
feedLinks: {
atom: urlcat(APP_URL, '/feed.xml')
},
copyright: '', // The copyright notice. If have none so I left it empty.
author: {
name: 'Baptiste Devessier',
email: 'baptiste@devessier.fr'
}
});
for (const blogPost of blogPosts) {
const href = urlcat(APP_URL, `/writing/${blogPost.slug}/`);
feed.addItem({
id: href,
title: blogPost.title,
link: href,
date: new Date(blogPost.datetime),
description: blogPost.description
});
}
setHeaders({
// The Atom feed is XML.
'Content-Type': 'application/atom+xml'
});
return new Response(feed.atom1());
};

Please note the path to the endpoint file. We can create endpoints that return any kind of data. If we create an endpoint whose path is src/routes/image.jpg/+server.ts, it can compute an image dynamically and return it. We can also handle other HTTP methods, like POST or DELETE. Though, if the form is also managed by SvelteKit, form actions may be a better solution. Pretty cool, isn’t it?

Next step, I add an alternate tag in my src/app.html file. This will allow RSS autodiscovery. All pages will be built on top of the base app.html file.

html
<link rel="alternate" type="application/atom+xml" href="/feed.xml" />

I statically build my portfolio on Netlify by using @sveltejs/adapter-static. It means that there will be no server to listen to requests made to endpoints on production. But this is fine…

When a build is launched, SvelteKit will build the JavaScript code that makes the application work, start a server to intercept requests and will start crawling each link between pages. Because there will be a link to /feed.xml on each of them, SvelteKit will visit this URL and save the generated XML file, as prerender option is set to true in src/routes/feed.xml/+server.ts file. The RSS Feed file will be generated automatically during each build!

permalinkFinal note

I have to admit that I am now considering starting to use RSS as a way to be kept informed. I downloaded NetNewsWire and began to add RSS feeds. For now, this is a great discovery!

SvelteKit is really flexible and this is amazing to build sites with it. Endpoints API is so generic that you can use it to handle HTTP requests from the outside as well as the generation of an RSS Feed. If you have not yet, try SvelteKit!

Join my mailing list

Get monthly insights, personal stories, and in-depth information about what I find helpful in web development as a freelancer.

Email advice once a month + Free XState report + Free course on XState

Want to see what it looks like? View the previous issues.

I value your privacy and will never share your email address.