RSS
the older of the two XML formats a feed is written in
What it is
RSS is an XML format for publishing a feed: one channel element that describes
a site and holds a list of item elements, each a post with a link, a date and
some text, at an address that feed readers fetch on a schedule. Its
specification spells the name out as Really Simple Syndication, many people say
“RSS feed” for a feed in any format, and RSS 1.0, “RDF Site Summary”, is a
separate format built on RDF rather than an earlier version of the one in use
today.
The format began at Netscape, which published RSS 0.90 in March 1999 and 0.91 that July. UserLand published its own 0.91 in June 2000, then 0.92 and, in August 2002, RSS 2.0. The Berkman Klein Center at Harvard Law School published 2.0.1, written by Dave Winer, in July 2003, and the RSS Advisory Board has kept the text since, under a Creative Commons licence. Its roadmap says the format is, for all practical purposes, frozen at 2.0.1. The board has published revisions of the document since, the current one in March 2009, but new needs are met by extensions in their own XML namespaces rather than by new versions of RSS.
A document is small. Its root is an rss element whose version attribute must
be 2.0, holding a single channel. The channel needs a title, a link and
a description. Every element of an item is optional, as long as the item has
at least a title or a description. Everything else, from pubDate and guid to
the channel’s image and ttl, is there when a publisher wants it:
<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
<channel>
<title>Example Notes</title>
<link>https://example.com/</link>
<description>Short notes on running servers.</description>
<item>
<title>Moving the database</title>
<link>https://example.com/notes/db-move/</link>
<guid isPermaLink="true">https://example.com/notes/db-move/</guid>
<pubDate>Sat, 17 Oct 2026 09:00:00 GMT</pubDate>
<description>Why the move took one evening.</description>
</item>
</channel>
</rss>
Why it matters
RSS is loose, and the looseness is what a publisher has to understand. An item’s
description may hold plain text or HTML escaped into the element, and nothing
in the file says which, so the reader decides. The guid is optional, so
without one a reader works out by itself whether an item is new. Dates follow
RFC 822, an email standard from 1982, as strings such as
Sat, 17 Oct 2026 09:00:00 GMT with English day and month names, and the
specification still allows a two-digit year. And the format has no way to
declare a base URL, so a relative link inside an item has nothing reliable to be
resolved against.
The board’s answer is the RSS Best Practices Profile, published in October 2007:
recommendations for documents that work across the wide range of software that
reads them. It asks for a guid on every item and for absolute URLs in links
and descriptions. It reports that the only date forms every aggregator it tested
handled were in Universal Time, ending in GMT, +0000 or -0000. It also
documents an atom:link with rel="self" that names the feed’s own address. A
feed written to the profile leaves its readers far less to guess.
Two extensions carry most of what a modern feed adds. atom:link borrows that
element from Atom. content:encoded, from a module first written for RSS 1.0,
holds an item’s full HTML. The profile describes using both together, the full
text in content:encoded and a shorter summary in description, and found
that, when an item carried both, six of the eight aggregators it tested
displayed content:encoded and ignored the summary. The enclosure element
attaches a media file to an item with three required attributes, its url, its
length in bytes and its MIME type.
Frozen is also a strength. A format that has not changed since 2003 is a fixed target, and a feed written to it today is read by software written against the same text years ago. Atom closes most of the gaps above by specification, so the case for publishing RSS as well is about readers rather than rigour: some take only RSS, and an RSS address handed out years ago is still being polled.
What it looks like in practice
This site publishes RSS 2.0 at /index.xml, next to an Atom feed and a JSON
Feed. The credits page explains why there are two XML feeds: all
three carry the full text, and there are two XML feeds rather than one because
some readers take only one of the two and neither is reliably the one. The same
page links the RSS feed to the
W3C Feed Validator, beside the Atom feed, so
that anyone can run the check without taking the site’s word for anything.
The page about reading the site from a terminal treats the feeds as
data. It says the portfolio is syndicated in three formats, each carrying the
full text of every item rather than a teaser, and fetches the RSS one with
nothing more than curl:
curl -s https://engineer.company/index.xml
Where it goes wrong
The channel’s picture is missing, and the validator objects. A reader shows
no image beside the feed’s name, and the W3C service warns about the image
format. RSS’s image element is the strictest picture element of the three feed
formats: GIF, JPEG or PNG only, at most 144 pixels wide and 400 high. A social
share card in WebP is the wrong file for it. This site’s RSS template points
image at its 144-pixel PNG icon instead, and the comment beside it records
that the WebP card had drawn an ImageUrlFormat warning, caught by validating
again after the change.
Items sort in the wrong order, and nothing reports it. A reader lists new
items below old ones, or shows them with the wrong date. RSS dates are strings,
so an ISO 8601 date, a misspelt layout or a day name in another language still
makes well-formed XML, and only the reader’s date parser notices. In Hugo, a
template’s Format method on a date writes English names, while the
time.Format function localises them; a Danish pubDate is not an RFC 822
date. This site formats each pubDate with the method, from a layout kept in
one partial template together with Atom’s, and the comment there says a typo in
either is not a build failure but a feed that parses and sorts wrongly in
somebody else’s reader.
Icons in a post draw nothing, and the validator lists errors. The full text
in content:encoded leaves its page, so anything that depends on the page goes
missing. An SVG icon that points into a sprite defined elsewhere on the page
draws nothing in a reader, and the W3C service flags the svg itself. This
site’s feeds get their headings without the brand’s cog divider for that reason;
the comment on that template records that the validator had reported twelve
Non-html tag: svg messages and six complaints about a role attribute.
Links inside a post go nowhere. A subscriber follows a link in an item and
lands on a missing page, or on nothing at all. A root-relative link such as
/notes/ works on the web page because the browser knows the page’s address,
but an RSS document cannot declare a base URL. The profile says a description
should not contain relative URLs and that an aggregator may try to resolve one
against the channel’s link; a reader that does not try leaves the link broken.
Write every link in a feed’s HTML as an absolute URL.
Two categories with the same word look like one. An item tagged in two
vocabularies shows a term twice, or a reader merges two terms that mean
different things. RSS’s category element takes an optional domain attribute
that names the vocabulary a term comes from. This site’s RSS template writes it
on every category, because, as its comment says, without the domain the two
vocabularies’ overlapping terms would read as duplicates.
Further reading
- RSS 2.0 Specification — the RSS Advisory Board’s text of the format, element by element, with the roadmap that declares it frozen.
- RSS Best Practices Profile — the board’s recommendations, with what it found when it tested real aggregators.
- RSS History — every version from Netscape’s 0.90 to the current text, with dates and publishers.
- RDF Site Summary (RSS) 1.0 — the separate RDF-based format that shares the name.
- RFC 822 — the 1982 email standard whose date and time syntax RSS still uses.