Skip to content

RSS feed should reference post images via <media:content> #18305

@myelinated-wackerow

Description

@myelinated-wackerow

Is your feature request related to a problem? Please describe.

The RSS feed at /latest/feed.xml (currently #18299) doesn't include image references for blog posts, even though every post's frontmatter already declares one and IBlogPost carries image?: string. Feed readers that surface thumbnails (Feedly, Inoreader, NetNewsWire, Reeder, most "magazine-style" aggregators) currently render entries with no preview, while the same posts on /latest/ and on the developers hub get a proper hero image via post.image or getBlogFallbackHero(post.href).

Concrete example: public/content/latest/building-on-ethereum-in-2026/index.md declares image: /images/developers/blog/latest-post-header-3.png. That asset exists at public/images/developers/blog/latest-post-header-3.png and is used in the on-site card, but it never appears in the feed XML.

Describe the solution you'd like

Emit a <media:content> element per item in app/[locale]/latest/feed.xml/route.ts (or feed/route.ts once #18299 lands), using the Yahoo Media RSS namespace.

Touch list:

  • Declare the namespace on the <rss> element: xmlns:media="http://search.yahoo.com/mrss/"
  • For each post, if post.image is set, emit <media:content url="<absolute>" medium="image" type="<mime>" />
    • Convert the frontmatter's relative path (/images/...) into an absolute URL by prefixing with SITE_URL (already used elsewhere in the route via getFullUrl)
    • Derive type from the extension (.png -> image/png, .jpg/.jpeg -> image/jpeg, .webp -> image/webp, .svg -> image/svg+xml)
  • For posts with no image frontmatter, fall back to getBlogFallbackHero(post.href) so every entry has a thumbnail (matches what the carousel and listing pages already do for consistency). The fallback returns a StaticImageData; emit its .src after resolving it against SITE_URL
  • Optional but recommended: also emit a <media:thumbnail url="..." /> alongside <media:content> for readers that prefer the simpler element

Describe alternatives you've considered

  • <enclosure> (RSS 2.0 native) instead of / in addition to <media:content>. Better-supported in the very long tail of feed readers, but requires length (byte size in bytes) and type on every entry. Computing length means stat'ing the file at build time, which adds I/O and edge cases for the fallback StaticImageData path. Could be added in a follow-up if real-world reader telemetry warrants it -- starting with <media:content> covers the modern reader landscape with no build-time file stat'ing.
  • Emit both <media:content> and <enclosure>. Maximum compatibility, roughly twice the implementation surface. Probably the right call eventually, but more than this single issue should scope.
  • Embed the image inline as HTML inside <description> via CDATA. Works for some readers but bypasses the dedicated media elements, fights with the existing escape-only <description> rendering, and produces inconsistent results across reader implementations. Reject.
  • Skip the fallback and only emit <media:content> when frontmatter declares an image. Simpler, but means future posts that forget the image: field have no thumbnail in feed readers. The fallback exists precisely so on-site cards never look broken; the same logic applies to the feed.

Additional context

  • The MRSS namespace URL is http://search.yahoo.com/mrss/ (not HTTPS -- this is the canonical XML namespace identifier even though the spec page itself has moved)
  • Validation: W3C Feed Validation Service flags MRSS as a recognized extension; specific element validation requires the MRSS spec validator
  • Independent of /latest/feed.xml returns infinite redirect loop #18299 (the redirect-loop bug). That bug blocks end users from fetching the feed in production, but doesn't affect the XML generation this issue is about. Either can land first

Acceptance criteria

  • <rss> element declares xmlns:media="http://search.yahoo.com/mrss/"
  • Every <item> in the feed contains exactly one <media:content url="..." medium="image" type="..." /> (or equivalent shape) pointing at an absolute URL
  • Items whose source post has image: in frontmatter reference that image; items without fall back to getBlogFallbackHero(post.href)
  • All url attributes are absolute (start with https://) and resolve to a 200 OK response on the live site
  • Pasting the feed into a modern reader (Feedly, Inoreader, NetNewsWire) shows a thumbnail next to each entry
  • Feed continues to validate as RSS 2.0; MRSS extension elements don't break compatibility with readers that ignore the namespace

Out of scope

  • Adding <enclosure> -- separate follow-up if needed
  • Per-locale image variants (none exist today; frontmatter images are language-neutral assets)
  • Image optimization, resizing, or CDN hosting changes
  • Atom or JSON Feed migration

Want to contribute?

  • Yes

Metadata

Metadata

Assignees

No one assigned

    Labels

    feature ✨This is enhancing something existing or creating something newneeds triage 📥This issue needs triaged before being worked on

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions