Namespace extensions: content:encoded, dc: and Media RSS
RSS 2.0 is small by design and extended by namespaces. Declaring them correctly is what makes full content, metadata and images work.
The extensions you will actually use
| Prefix | Namespace URI | Adds |
|---|---|---|
content | http://purl.org/rss/1.0/modules/content/ | content:encoded, the full item HTML |
dc | http://purl.org/dc/elements/1.1/ | dc:creator, dc:date, dc:language |
media | http://search.yahoo.com/mrss/ | Images, thumbnails, video and player metadata |
atom | http://www.w3.org/2005/Atom | atom:link with rel="self" |
itunes | http://www.itunes.com/dtds/podcast-1.0.dtd | Podcast metadata |
podcast | https://podcastindex.org/namespace/1.0 | Podcasting 2.0 metadata |
slash | http://purl.org/rss/1.0/modules/slash/ | slash:comments, comment counts |
sy | http://purl.org/rss/1.0/modules/syndication/ | Update period and frequency |
<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:media="http://search.yahoo.com/mrss/"
xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>Release Notes</title>
<link>https://example.com/releases</link>
<description>Product changes, weekly.</description>
<language>en-gb</language>
<atom:link href="https://example.com/feed.xml" rel="self" type="application/rss+xml"/>
<lastBuildDate>Thu, 18 Sep 2026 09:00:00 +0100</lastBuildDate>
<item>
<title>Platform 3.2</title>
<link>https://example.com/releases/2026-09-platform-3-2</link>
<guid isPermaLink="false">release-2026-09-platform-3-2</guid>
<pubDate>Thu, 18 Sep 2026 09:00:00 +0100</pubDate>
<dc:creator>Platform Team</dc:creator>
<!-- summary for readers that show a teaser -->
<description>Streaming transforms and faster cold start.</description>
<!-- full HTML for readers that show the whole article -->
<content:encoded><![CDATA[<p>Streaming transforms and faster cold start.</p>
<img src="https://example.com/img/3-2.png" alt="Dashboard"/>]]></content:encoded>
<media:thumbnail url="https://example.com/img/3-2-300.png" width="300" height="169"/>
<media:content url="https://example.com/img/3-2.png" medium="image" width="1200" height="675"/>
</item>
</channel>
</rss>Pitfalls with extensions
- A prefix that is used but not declared on the
rsselement makes the document not well formed. Feed validators report this as a namespace error, and readers drop the item. - The prefix itself is arbitrary — only the URI matters. Copying a feed and renaming the prefix is safe; changing the URI is not.
- Inside
content:encoded, use CDATA or escape every<. Mixing both is where most broken feeds come from. descriptionandcontent:encodedserve different readers. Fill both rather than duplicating megabytes into each.media:contentandenclosureare different mechanisms: an enclosure is a downloadable asset, media content is metadata about a resource.- Extension order inside
itemis flexible, but keeping a consistent order makes diffs readable when you debug a feed.
import html
def item_xml(it) -> str:
"""Escape for text content; use CDATA only where the schema expects markup."""
def esc(s: str) -> str:
return html.escape(s, quote=True)
parts = [
" <item>",
" <title>" + esc(it.title) + "</title>",
" <link>" + esc(it.url) + "</link>",
' <guid isPermaLink="false">' + esc(it.id) + "</guid>",
" <pubDate>" + it.published.strftime("%a, %d %b %Y %H:%M:%S %z") + "</pubDate>",
" <description>" + esc(it.summary) + "</description>",
# Nothing may be literally ]]> inside a CDATA section, so split it
" <content:encoded><![CDATA["
+ it.html.replace("]]>", "]]]]><![CDATA[>")
+ "]]></content:encoded>",
" </item>",
]
return "\n".join(parts)⚠️
The
]]> sequence inside a CDATA section ends it early and produces a feed that parses as XML but has lost most of its content. If the HTML you embed comes from a rich text editor or a user, always split the sequence as shown above, or escape instead of using CDATA.FAQ
Do readers show content:encoded or description?
Most prefer content:encoded when present and fall back to description. Podcast and news applications vary, which is why supplying both is standard practice.
Can I invent my own namespace?
Yes, but no reader will understand it. Publish it with a documented URI if you need custom data, and keep the standard fields complete so a strict reader still renders the item.
Related
The RSS 2.0 feed format Full-text versus summary feeds
Last refreshed 2026-09-18.