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

PrefixNamespace URIAdds
contenthttp://purl.org/rss/1.0/modules/content/content:encoded, the full item HTML
dchttp://purl.org/dc/elements/1.1/dc:creator, dc:date, dc:language
mediahttp://search.yahoo.com/mrss/Images, thumbnails, video and player metadata
atomhttp://www.w3.org/2005/Atomatom:link with rel="self"
ituneshttp://www.itunes.com/dtds/podcast-1.0.dtdPodcast metadata
podcasthttps://podcastindex.org/namespace/1.0Podcasting 2.0 metadata
slashhttp://purl.org/rss/1.0/modules/slash/slash:comments, comment counts
syhttp://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 rss element 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.
  • description and content:encoded serve different readers. Fill both rather than duplicating megabytes into each.
  • media:content and enclosure are different mechanisms: an enclosure is a downloadable asset, media content is metadata about a resource.
  • Extension order inside item is 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.

The RSS 2.0 feed format Full-text versus summary feeds

Last refreshed 2026-09-18.