Skip to content

Feed

a page's updates, in a format you subscribe to

What it is

A feed is a file at a fixed address that lists a site’s latest items in a form software can read, each with a title, a date, an identifier that does not change and usually the text itself, so that a program can fetch it on a schedule and show a person only what is new. It also goes by web feed or syndication feed, and many people say “RSS feed” for any of them, whatever format sits underneath.

What sets it apart is the direction of travel. A newsletter is pushed: the publisher keeps a list of addresses and sends to every one. A feed is pulled: the publisher leaves one file on the server, and each subscriber’s feed reader fetches it, compares it with the copy it saw last time and keeps the items it has not met before. The publisher never learns who subscribed, the subscriber never hands over an email address, and leaving is a matter of deleting one line in a reader.

Three formats carry nearly all feeds on the web. RSS 2.0 is XML, dates its items in the style of RFC 822 (Sat, 07 Sep 2002 00:00:01 GMT) and is declared frozen by its own specification. Atom, published by the IETF as RFC 4287 in December 2005, is also XML and stricter: every feed and every entry carries a permanent id and an updated timestamp in RFC 3339 form, and an author must be named somewhere. JSON Feed, at version 1.1 since August 2020, says the same things in JSON for developers who would rather not parse XML.

A page tells software where its feeds live with <link rel="alternate"> elements in its head, each naming a media type: application/rss+xml, application/atom+xml or application/feed+json. That is how a reader finds the feed from nothing more than the site’s ordinary address.

Why it matters

The first decision is whether to publish one at all. A feed is one more output to template, validate and keep stable for years, for an audience smaller than a social network’s. Against that, it is the only subscription channel that needs no platform, no account and no mailing list, and no ranking algorithm sits between a post and the people who asked to see it.

The second decision is which formats. Some readers take only RSS and some only Atom, and there is no telling in advance which one a given subscriber’s reader wants. Publishing both covers the gap for the price of a second template, and JSON Feed adds a third for software written by people who would rather handle JSON. Each extra format is another file to keep in step: same items, same identifiers, same dates.

The third is how much text to put in each item. A full-text feed lets people read the whole piece in their reader, which is much of the point of a reader, and costs the publisher page views. A summary-only feed sends every reader to the site for each item. Neither is wrong; the choice is between how far the writing travels and how often the page itself is visited.

Whatever the answers, the address is a commitment. Readers poll the URL they were given, on a schedule each reader picks for itself (RSS lets a feed suggest one in minutes with ttl, and a reader may ignore it), and many keep polling for years. Once a feed address is out, it stays.

What it looks like in practice

This site publishes all three formats from its home page, at /index.xml (RSS), /atom.xml (Atom) and /feed.json (JSON Feed). The credits page lists them and the services that check them: 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 W3C Feed Validator checks the Atom and RSS feeds, and the JSON Feed Validator checks the third, which the W3C service does not cover because it predates the format. The W3C service warns that most entries share a modification date. The page keeps that warning rather than hide it: the dates come from git history, and most of the pages were written in the same few commits.

The contact page offers the feeds as a way to follow the company without an account, next to its social profiles, and repeats that all three carry the full text of everything published.

None of the three is written by hand or produced on request. In the project that built the site, the site is generated entirely at build time with no runtime backend, every page is published in four representations from one content tree, and the home page adds three syndication feeds and an installable application manifest on top.

Where it goes wrong

Every old item turns up again as new. After a redesign, a domain move or a template change, subscribers see dozens of items they read months ago. Readers recognise an item by its identifier, Atom’s id, RSS’s guid or JSON Feed’s id, and when that string changes, the item is new to them. RFC 4287 is explicit that an entry’s id must survive relocation, migration and republishing. A permalink makes a good identifier only while the site promises to keep the old string after a move. In RSS, also say what the guid is: the specification defaults isPermaLink to true, and this site’s RSS template writes isPermaLink="true" anyway, because a reader that guesses the other way re-imports every item as a duplicate.

The feed claims to have changed on every build. The feed-level date moves each time the site is rebuilt, whether or not anything was published, so software that watches that date for news fires on nothing. The cause is a template that stamps the clock at build time. RSS defines lastBuildDate as the “last time the content of the channel changed”, and Atom’s feed-level updated means the same, so the date should come from the newest item instead. This site’s Atom template takes it from the newest entry for exactly that reason.

The feed stops parsing after a typography change. Readers report the feed as broken, and a validator points at an undefined entity in the first article with a curly quote. XML predefines five named entities, lt, gt, amp, apos and quot, while HTML defines hundreds more. A Markdown renderer that writes quotes and dashes as HTML’s named entities produces markup that is fine in a page and fatal inside an XML element. Escape the HTML before it goes in, which is what Atom’s type="html" content expects, or wrap it in a CDATA section, which the RSS Best Practices Profile allows for content:encoded. This site’s Atom template escapes its content, and the comment beside it records that, written raw, the feed did not parse at all.

Subscribers drift away after a move, and nobody hears about it. A feed has no unsubscribe button and no list that shrinks, so the only sign is silence. The feed’s address changed, or its file was removed, and every reader polling the old URL now gets an error. Keep the old address answering, either with the feed itself or with a permanent redirect. This site keeps its RSS at /index.xml, the default path of the generator it is built with, because that is the address existing readers poll; and in a language it does not announce, it still writes well-formed feeds carrying zero items, so a reader gets a valid document rather than a 404.

Two feeds collapse into one in a subscribe dialog. A browser extension or a reader offers a single feed where the page declares two. Two alternate links with the same type and the same title look to such a tool like one feed, and it lists whichever it saw last. Give each its own title; this site’s pages name theirs with the site’s name followed by “(RSS)”, “(Atom)” or “(JSON Feed)”.

Further reading

Glossary