Overview
Create stable RSS 2.0 and Atom 1.0 feed endpoints so articles are discoverable by feed readers, search engines, and browser recommendation engines. Feeds should include recent articles with proper metadata for syndication.
Current State
- Existing feed page at
apps/the_monkeys/src/app/feed/layout.tsx (HTML-based, personal Following feed)
- No machine-readable XML feed endpoints
- No RSS or Atom feed generation
Requirements
1. Create RSS 2.0 Feed Endpoint (/feed.xml)
Location: apps/the_monkeys/src/app/feed.xml/route.ts or dynamic route
Response:
- Content-Type:
application/rss+xml; charset=utf-8
- Valid RSS 2.0 structure per W3C spec
- Latest N articles (configurable, default: 50)
- Include for each item:
\u003ctitle\u003e - Article title
\u003clink\u003e - Article URL
\u003cguid isPermaLink="false"\u003e - Unique article ID
\u003cpubDate\u003e - Published date in RFC 2822 format (e.g., Mon, 06 Sep 2021 00:01:00 +0000)
\u003cdescription\u003e - Article summary/excerpt (wrapped in CDATA)
\u003cenclosure\u003e - Thumbnail image with MIME type
\u003cauthor\u003e - Author email or username
\u003ccategory\u003e - Article topics/tags
Example RSS structure:
\u003c?xml version="1.0" encoding="UTF-8"?\u003e
\u003crss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"\u003e
\u003cchannel\u003e
\u003ctitle\u003eMonkeys - Quality Blogs\u003c/title\u003e
\u003clink\u003ehttps://monkeys.com.co\u003c/link\u003e
\u003cdescription\u003eQuality blogs on technology, business, science, lifestyle \u0026 more\u003c/description\u003e
\u003clanguage\u003een-us\u003c/language\u003e
\u003cpubDate\u003eMon, 06 Sep 2021 00:01:00 +0000\u003c/pubDate\u003e
\u003clastBuildDate\u003eMon, 06 Sep 2021 00:01:00 +0000\u003c/lastBuildDate\u003e
\u003citem\u003e
\u003ctitle\u003eArticle Title\u003c/title\u003e
\u003clink\u003ehttps://monkeys.com.co/blog/article-slug-123\u003c/link\u003e
\u003cguid isPermaLink="false"\u003e123\u003c/guid\u003e
\u003cpubDate\u003eMon, 06 Sep 2021 00:01:00 +0000\u003c/pubDate\u003e
\u003cdescription\u003e\u003c![CDATA[Article summary...]]\u003e\u003c/description\u003e
\u003cenclosure url="https://image-url.png" length="0" type="image/png" /\u003e
\u003ccategory\u003eTechnology\u003c/category\u003e
\u003cauthor\u003eauthor@monkeys.com.co\u003c/author\u003e
\u003c/item\u003e
\u003c/channel\u003e
\u003c/rss\u003e
2. Create Atom 1.0 Feed Endpoint (/atom.xml)
Location: apps/the_monkeys/src/app/atom.xml/route.ts or dynamic route
Response:
- Content-Type:
application/atom+xml; charset=utf-8
- Valid Atom 1.0 structure per RFC 4287
- Latest N articles (configurable, default: 50)
- Include for each entry:
\u003ctitle\u003e - Article title
\u003clink href=""\u003e - Article URL with rel="alternate"
\u003cid\u003e - Unique article ID (URN or URL)
\u003cpublished\u003e - Published date in ISO 8601 format
\u003cupdated\u003e - Last modified date in ISO 8601 format
\u003csummary\u003e - Article summary
\u003ccontent type="html"\u003e - Optional: full article content
\u003clink rel="enclosure"\u003e - Thumbnail image
\u003cauthor\u003e - Author name and optional email
\u003ccategory term=""\u003e - Article topics/tags
Example Atom structure:
\u003c?xml version="1.0" encoding="utf-8"?\u003e
\u003cfeed xmlns="http://www.w3.org/2005/Atom"\u003e
\u003ctitle\u003eMonkeys - Quality Blogs\u003c/title\u003e
\u003clink href="https://monkeys.com.co"/\u003e
\u003clink href="https://monkeys.com.co/atom.xml" rel="self"/\u003e
\u003cid\u003eurn:uuid:monkeys-feed\u003c/id\u003e
\u003cupdated\u003e2021-09-06T00:01:00Z\u003c/updated\u003e
\u003centry\u003e
\u003ctitle\u003eArticle Title\u003c/title\u003e
\u003clink href="https://monkeys.com.co/blog/article-slug-123" rel="alternate"/\u003e
\u003clink href="https://image-url.png" rel="enclosure" type="image/png"/\u003e
\u003cid\u003eurn:uuid:123\u003c/id\u003e
\u003cpublished\u003e2021-09-06T00:01:00Z\u003c/published\u003e
\u003cupdated\u003e2021-09-06T00:01:00Z\u003c/updated\u003e
\u003csummary\u003eArticle summary...\u003c/summary\u003e
\u003cauthor\u003e
\u003cname\u003eAuthor Name\u003c/name\u003e
\u003c/author\u003e
\u003ccategory term="Technology"/\u003e
\u003c/entry\u003e
\u003c/feed\u003e
Implementation Tasks
1. Create Feed Generation Utility
File: apps/the_monkeys/src/services/blog/feedGenerator.ts
generateRSSFeed() - Returns RSS XML string
generateAtomFeed() - Returns Atom XML string
fetchRecentArticles(limit) - Fetches articles from API
escapeXml() - XML entity encoding utility
formatRFC2822Date() - Convert to RSS date format
formatISO8601Date() - Convert to Atom date format
2. Create Route Handlers
File: apps/the_monkeys/src/app/feed.xml/route.ts
export async function GET() {
const articles = await fetchRecentArticles(50);
const xml = generateRSSFeed(articles);
return new Response(xml, {
headers: {
'Content-Type': 'application/rss+xml; charset=utf-8',
'Cache-Control': 'public, max-age=3600', // Cache for 1 hour
},
});
}
File: apps/the_monkeys/src/app/atom.xml/route.ts
export async function GET() {
const articles = await fetchRecentArticles(50);
const xml = generateAtomFeed(articles);
return new Response(xml, {
headers: {
'Content-Type': 'application/atom+xml; charset=utf-8',
'Cache-Control': 'public, max-age=3600',
},
});
}
3. Add Feed Discovery Links
Update apps/the_monkeys/src/app/layout.tsx metadata to include feed autodiscovery:
alternates: {
feed: 'https://monkeys.com.co/feed.xml', // Add RSS feed link
type: 'application/rss+xml',
},
4. Handle Special Characters & Encoding
- Properly escape XML entities (
\u003c, \u003e, \u0026, \", ')
- Handle HTML content in descriptions (use CDATA sections)
- Ensure valid UTF-8 encoding
- Handle missing/null fields gracefully
Acceptance Criteria
Files to Create
apps/the_monkeys/src/services/blog/feedGenerator.ts - Feed generation logic
apps/the_monkeys/src/app/feed.xml/route.ts - RSS endpoint
apps/the_monkeys/src/app/atom.xml/route.ts - Atom endpoint
__tests__/feedGenerator.test.ts - Unit tests
Testing Checklist
Notes
- Feeds should be stable and immutable (use article IDs, not timestamps)
- Consider pagination for large feeds (alternate links to next/previous page)
- Monitor feed fetch performance (may need caching optimization)
Related
Overview
Create stable RSS 2.0 and Atom 1.0 feed endpoints so articles are discoverable by feed readers, search engines, and browser recommendation engines. Feeds should include recent articles with proper metadata for syndication.
Current State
apps/the_monkeys/src/app/feed/layout.tsx(HTML-based, personal Following feed)Requirements
1. Create RSS 2.0 Feed Endpoint (
/feed.xml)Location:
apps/the_monkeys/src/app/feed.xml/route.tsor dynamic routeResponse:
application/rss+xml; charset=utf-8\u003ctitle\u003e- Article title\u003clink\u003e- Article URL\u003cguid isPermaLink="false"\u003e- Unique article ID\u003cpubDate\u003e- Published date in RFC 2822 format (e.g.,Mon, 06 Sep 2021 00:01:00 +0000)\u003cdescription\u003e- Article summary/excerpt (wrapped in CDATA)\u003cenclosure\u003e- Thumbnail image with MIME type\u003cauthor\u003e- Author email or username\u003ccategory\u003e- Article topics/tagsExample RSS structure:
\u003c?xml version="1.0" encoding="UTF-8"?\u003e \u003crss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"\u003e \u003cchannel\u003e \u003ctitle\u003eMonkeys - Quality Blogs\u003c/title\u003e \u003clink\u003ehttps://monkeys.com.co\u003c/link\u003e \u003cdescription\u003eQuality blogs on technology, business, science, lifestyle \u0026 more\u003c/description\u003e \u003clanguage\u003een-us\u003c/language\u003e \u003cpubDate\u003eMon, 06 Sep 2021 00:01:00 +0000\u003c/pubDate\u003e \u003clastBuildDate\u003eMon, 06 Sep 2021 00:01:00 +0000\u003c/lastBuildDate\u003e \u003citem\u003e \u003ctitle\u003eArticle Title\u003c/title\u003e \u003clink\u003ehttps://monkeys.com.co/blog/article-slug-123\u003c/link\u003e \u003cguid isPermaLink="false"\u003e123\u003c/guid\u003e \u003cpubDate\u003eMon, 06 Sep 2021 00:01:00 +0000\u003c/pubDate\u003e \u003cdescription\u003e\u003c![CDATA[Article summary...]]\u003e\u003c/description\u003e \u003cenclosure url="https://image-url.png" length="0" type="image/png" /\u003e \u003ccategory\u003eTechnology\u003c/category\u003e \u003cauthor\u003eauthor@monkeys.com.co\u003c/author\u003e \u003c/item\u003e \u003c/channel\u003e \u003c/rss\u003e2. Create Atom 1.0 Feed Endpoint (
/atom.xml)Location:
apps/the_monkeys/src/app/atom.xml/route.tsor dynamic routeResponse:
application/atom+xml; charset=utf-8\u003ctitle\u003e- Article title\u003clink href=""\u003e- Article URL withrel="alternate"\u003cid\u003e- Unique article ID (URN or URL)\u003cpublished\u003e- Published date in ISO 8601 format\u003cupdated\u003e- Last modified date in ISO 8601 format\u003csummary\u003e- Article summary\u003ccontent type="html"\u003e- Optional: full article content\u003clink rel="enclosure"\u003e- Thumbnail image\u003cauthor\u003e- Author name and optional email\u003ccategory term=""\u003e- Article topics/tagsExample Atom structure:
\u003c?xml version="1.0" encoding="utf-8"?\u003e \u003cfeed xmlns="http://www.w3.org/2005/Atom"\u003e \u003ctitle\u003eMonkeys - Quality Blogs\u003c/title\u003e \u003clink href="https://monkeys.com.co"/\u003e \u003clink href="https://monkeys.com.co/atom.xml" rel="self"/\u003e \u003cid\u003eurn:uuid:monkeys-feed\u003c/id\u003e \u003cupdated\u003e2021-09-06T00:01:00Z\u003c/updated\u003e \u003centry\u003e \u003ctitle\u003eArticle Title\u003c/title\u003e \u003clink href="https://monkeys.com.co/blog/article-slug-123" rel="alternate"/\u003e \u003clink href="https://image-url.png" rel="enclosure" type="image/png"/\u003e \u003cid\u003eurn:uuid:123\u003c/id\u003e \u003cpublished\u003e2021-09-06T00:01:00Z\u003c/published\u003e \u003cupdated\u003e2021-09-06T00:01:00Z\u003c/updated\u003e \u003csummary\u003eArticle summary...\u003c/summary\u003e \u003cauthor\u003e \u003cname\u003eAuthor Name\u003c/name\u003e \u003c/author\u003e \u003ccategory term="Technology"/\u003e \u003c/entry\u003e \u003c/feed\u003eImplementation Tasks
1. Create Feed Generation Utility
File:
apps/the_monkeys/src/services/blog/feedGenerator.tsgenerateRSSFeed()- Returns RSS XML stringgenerateAtomFeed()- Returns Atom XML stringfetchRecentArticles(limit)- Fetches articles from APIescapeXml()- XML entity encoding utilityformatRFC2822Date()- Convert to RSS date formatformatISO8601Date()- Convert to Atom date format2. Create Route Handlers
File:
apps/the_monkeys/src/app/feed.xml/route.tsFile:
apps/the_monkeys/src/app/atom.xml/route.ts3. Add Feed Discovery Links
Update
apps/the_monkeys/src/app/layout.tsxmetadata to include feed autodiscovery:4. Handle Special Characters & Encoding
\u003c,\u003e,\u0026,\",')Acceptance Criteria
/feed.xmlreturns valid RSS 2.0 (validate with https://validator.w3.org/feed/)/atom.xmlreturns valid Atom 1.0 (validate with https://validator.w3.org/feed/)Files to Create
apps/the_monkeys/src/services/blog/feedGenerator.ts- Feed generation logicapps/the_monkeys/src/app/feed.xml/route.ts- RSS endpointapps/the_monkeys/src/app/atom.xml/route.ts- Atom endpoint__tests__/feedGenerator.test.ts- Unit testsTesting Checklist
Notes
Related