
Most people who ask “how do I add RSS to my site” have already answered their own question without realizing it. If you’re running WordPress, Ghost, Hugo, or almost any mainstream publishing platform, a feed is already sitting at a predictable URL, has been since the day you launched, and nobody has ever looked at it. The actual project isn’t building a feed from nothing — it’s finding the one you have, checking that it isn’t quietly broken, and making it easy for someone else’s software to discover.
That last part matters more than it sounds. A working feed that nothing can find is functionally the same as no feed at all.
Check These URLs Before You Build Anything
Try these first, in order, before writing a line of XML.

WordPress ships feeds by default — plural. Core exposes an RSS 2.0 feed, an Atom feed, a comments feed, and even legacy RSS 0.92 and RDF (RSS 1.0) variants through template functions like bloginfo('rss2_url') and bloginfo('atom_url'). In practice, appending /feed/ to your homepage gets you the main one on almost any install.
Ghost generates RSS automatically for the whole site, and separately for every tag and author page, by appending /rss/ to the URL — yoursite.com/tag/news/rss/ works the same way yoursite.com/rss/ does. It’s on by default; a site owner has to explicitly set rss: false in the routing config to turn it off.
Hugo builds RSS feeds at build time for the home page, every section, every taxonomy, and every term, with zero configuration — the site-wide one lands at /index.xml. No plugin required.
Jekyll is the outlier: it does nothing by default. You need the jekyll-feed plugin, which then writes an Atom feed — not RSS — to /feed.xml. Worth flagging because Jekyll’s own plugin README describes Atom as “RSS 3.0,” which is a marketing shorthand, not a technical fact; Atom is a separate IETF standard (RFC 4287) with no version relationship to RSS at all.
Substack puts a feed at /feed for every publication, whether it lives on a *.substack.com subdomain or a custom domain. Free posts ship full text; paid posts are truncated to a preview in the feed regardless of what the writer would otherwise choose — the platform makes that call for you.
Eleventy needs the @11ty/eleventy-plugin-rss plugin, which can emit Atom, RSS, or JSON Feed depending on how you configure it — again, nothing ships by default.
If none of the obvious paths work, view your homepage’s source and search for rel="alternate" — if a feed exists anywhere, that tag is the most reliable way to find its actual URL rather than guessing.
What Actually Has to Be There
Here’s the part that surprises people once they open a real feed file: the bar for a valid RSS 2.0 document is startlingly low. The specification, maintained since 2003 by Harvard’s Berkman Center with a current derivative kept by the RSS Advisory Board, requires exactly three elements inside <channel> — title, link, and description. That’s the entire mandatory surface of a feed.
Individual <item> entries require even less. The spec is explicit: “All elements of an item are optional, however at least one of title or description must be present.” Everything you’d assume is mandatory — a link back to the post, a pubDate, a unique ID — is technically optional. That’s not a loophole; it’s the reason so many feeds in the wild are missing exactly those fields.
A minimally correct feed looks like this:
<?xml version="1.0" encoding="utf-8"?><rss version="2.0"> <channel> <title>Your Site Name</title> <link>https://yoursite.com/</link> <description>What your site is about.</description> <item> <title>Your latest post</title> <link>https://yoursite.com/your-latest-post/</link> <description>A short summary of the post.</description> <pubDate>Thu, 27 Aug 2026 09:30:00 +0000</pubDate> <guid isPermaLink="false">tag:yoursite.com,2026:post-482</guid> </item> </channel></rss>Atom, by contrast, makes the fields a consumer actually needs mandatory: every entry must carry a title, an updated timestamp, and a stable id distinct from any URL. RSS 2.0 is easier to write; Atom is harder to write but far less ambiguous to parse. If your platform gives you a choice, that trade-off is the whole decision.
Make Your Feed Discoverable: the Autodiscovery Tag
A feed at a working URL still isn’t “added” to your site in any meaningful sense until a reader can find it without you handing over the exact link. That’s the job of one <link> tag in your page’s <head>:

<link rel="alternate" type="application/rss+xml" title="Your Site" href="https://yoursite.com/feed/">The rules, per the RSS Advisory Board’s autodiscovery spec, are specific: rel must be exactly alternate, type must match the feed’s actual MIME type (application/rss+xml for RSS), and href should be an absolute URL. This one tag is what lets someone paste your homepage into a feed reader and have it “just work” instead of hunting for /feed/ themselves.
Here’s a wrinkle worth checking on your own site rather than assuming: on WordPress, the function that prints this tag only fires when the active theme explicitly declares support for it via add_theme_support('automatic-feed-links'). WordPress’s own default themes do this, so most out-of-the-box installs are covered — but a custom theme, an older theme, or a heavily customized page builder might not, even though the feed itself is still running underneath. It costs nothing to view-source your own homepage and check.
Hugo is the opposite case: it never adds this tag automatically, even though it generates the feed files. You have to place the link in your theme’s head template yourself. Jekyll’s jekyll-feed plugin, once installed, gives you a one-line helper — {% feed_meta %} — that outputs the tag for you. Three platforms, three different defaults, and the only way to know which one you have is to check.
Full Post or Just a Teaser? The Real Trade-off
Once your feed exists and is discoverable, the next decision is what actually goes inside <description>: the whole post, or a summary that sends readers back to your site to finish it. There’s no universally correct answer here, and you should be suspicious of anyone who tells you there is.

The case for full text: it’s what most subscribers actually want. It reads offline. It survives your site being slow, redesigned, or temporarily down. And in a channel where unsubscribing is one click, full text is a goodwill signal.
The case for summaries: pageviews are the unit ad revenue, analytics, and A/B testing are built around, and a full-text feed converts a visit into a fetch you can’t monetize or reliably count. Anything that lives on the page rather than in the feed — related-post modules, newsletter signup prompts, disclosures — simply doesn’t reach a full-text subscriber. Full text also makes wholesale republication of your writing trivial for anyone who wants to scrape it.
This is a business decision, not an ethics test, and ad-funded and product-funded sites can rationally land in different places. Substack’s own default is instructive: full text for free posts, because the platform’s business model runs on subscriptions rather than page-view advertising, so there’s nothing to lose by giving the whole post away. A site paying its bills through display ads has the opposite incentive built into its numbers. There’s also a middle ground worth knowing about: full text with a short footer linking to the canonical post, or full text reserved for evergreen material while news-style posts stay as summaries.
Mechanically, the choice comes down to which element carries the content — a plain <description> for a summary, or content:encoded (borrowed from the RSS 1.0 Content module) for full HTML. Atom sidesteps the ambiguity with an explicit type attribute on <content> that tells a reader whether it’s getting text, HTML, or XHTML.
Five Ways a Feed Quietly Breaks
Feeds fail silently far more often than they fail loudly. None of these throw an error a site owner would ever see:

- Invalid XML from unescaped characters. The single most common validator error is an undefined entity — usually
leaking in from HTML content, which is valid in HTML but not in XML. The fix is or instead. - Wrong
Content-Typeheader. A feed served astext/htmlortext/plaininstead ofapplication/rss+xmlcan render as raw XML text in a browser or get silently rejected by stricter readers, even when the XML itself is perfectly valid. - Relative URLs inside content. A link or image path that resolves fine on your own page (
/images/photo.jpg) breaks the moment it’s pulled into a reader running on a different domain, because there’s no page context to resolve it against. - Missing or unstable GUIDs. The
isPermaLinkattribute on<guid>defaults totrue— omitting it is actually an assertion that the value is a working permalink, not a neutral choice. If that value changes because of a URL restructuring, a platform migration, or a stray tracking parameter, a reader that keys its “seen” list on the guid treats the edited post as brand new. This is the actual mechanism behind the classic “why did my reader show fifty duplicate posts” complaint. - Dates in the wrong format. RSS 2.0 dates follow RFC 822 style (
Thu, 27 Aug 2026 09:30:00 +0000); Atom and JSON Feed use RFC 3339 (2026-08-27T09:30:00Z). The two share no syntax, and mixing them up doesn’t throw an error — the XML still parses. It just makes ordering silently wrong, and a reader that can’t parse the date falls back to fetch time, so your whole archive can appear to have been published today.
Validate Before You Trust It
The W3C Feed Validator, at validator.w3.org/feed/, exists specifically to “check the syntax of Atom or RSS feeds,” and it covers RSS 1.0, RSS 2.0, and Atom 1.0. Paste your feed URL in, read every warning as well as every error, and fix both — warnings catch deprecated practices and missing recommended elements that won’t break anything today but will eventually.
One honest limit: validating a feed proves it’s well-formed, not that it’s good. The validator cannot tell you your guids are unstable across edits, that your dates are syntactically valid but wrong, or that you meant to publish full text and shipped teasers by accident. Treat it as the floor, not the finish line — and re-run it after any theme or plugin change, since those are the moments feeds most often break without anyone noticing.
Frequently Asked Questions
Do I need to build a feed from scratch? Almost never, if you’re on a mainstream platform. WordPress, Ghost, and Hugo all generate one automatically; the work is checking it exists, finding its URL, and confirming it’s discoverable — not writing XML by hand.
How do I tell if my feed is RSS or Atom? Look at the root element. <rss version="2.0"> wrapping a <channel> is RSS. <feed xmlns="http://www.w3.org/2005/Atom"> with no wrapper is Atom. Jekyll’s default plugin produces Atom even though people casually call the whole category “RSS.”
My platform doesn’t seem to have a feed at all — what now? Check the platform’s own documentation for a feed plugin before assuming you have to write one manually. Static-site generators in particular vary widely: Hugo builds feeds with zero setup, while Jekyll and Eleventy both need a plugin added explicitly.
Does having a feed expose anything about who reads it? A feed itself doesn’t track your visitors — there’s no beacon, no login, no analytics baked into the format. What it does expose is the mechanics of who’s fetching it (an IP address and a User-Agent on some schedule), and if a lot of your readers use the same hosted reader service, that service sees their whole subscription list, not just yours. It’s a separate question from anything covered here, and worth its own read if you’re deciding how much to care.
Should I just serve full text and stop worrying about it? Only if the trade-off actually fits your site. If you run ads or depend on pageview metrics, a full-text feed gives away the thing your revenue is built on. If you’re not monetizing views, there’s very little reason not to.
If you want the deeper story behind the format itself — the branching version history, what actually happened to RSS after Google Reader shut down, and why podcasting quietly kept it alive — that’s covered in our companion piece on what RSS actually is. This one is deliberately narrower: find what you already have, and don’t let it quietly rot.
Recommended Resources
Start with the free version first. Everything in this article — the three required channel elements, the autodiscovery <link> rules, the guid trap — comes straight from two short, free, still-current documents: the RSS 2.0 Specification maintained by Harvard’s Berkman Center, and the RSS Autodiscovery Specification from the RSS Advisory Board. Read both before you spend money on anything — together they’re shorter than this article.
If you want a book on your shelf for the mechanics of building and publishing feeds, the RSS/Atom book shelf is a genuine time capsule — nothing has been written on the format itself since the mid-2000s, because the format stopped changing and the industry moved on to writing about what runs on top of it. That’s not a knock on these titles; the mechanics they cover (required elements, autodiscovery, content encoding) haven’t changed since:
- RSS and Atom in Action — the most complete of the format books, covering both formats side by side, which suits the RSS-vs-Atom decision this article walks through.
- Developing Feeds with RSS and Atom — O’Reilly’s take on the same mechanics, useful if you want a second explanation of the publishing side specifically.
- Beginning RSS and Atom Programming — the most introductory of the three, a reasonable start if you’ve never opened a feed file before.
None of these will teach you anything the free specs above don’t already say — they’re for people who prefer a book to a standards document, not a substitute for reading the source.