Adding RSS Feed to Next.js blog

How I implemented RSS feed using Next.js App Router's route handlers instead of external packages.

Dec 14, 2024 · 3 min read

I recently decided to add an RSS feed to my blog. Like any developer, my first instinct was to Google "how to add RSS feed to Next.js blog" 😄

During my research, I found that many tutorials suggested using the rss npm package. One particular tutorial by Dave Gray caught my attention. It seemed straightforward enough, so I decided to give it a try.

However, things didn't go quite as planned. Despite following the tutorial, I ran into some issues getting it to work with my Next.js App Router setup. That's when I remembered that I had already implemented a sitemap for my blog using Next.js's built-in features without any external packages. After some experimentation with route handlers and XML generation, I managed to get it working!

Here's how I implemented it using Next.js App Router's route handlers, no external packages needed.

Basic Structure

// app/feed/route.ts
export async function GET() {
    const blogs: Blogs = await getMetadata()
    // Generate and return RSS XML
}

This creates a route handler at /feed that responds to GET requests. We use getMetadata() to fetch all blog posts.

XML Generation

1. XML Header and Channel Info

<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>realvjy's story</title>
        <link>https://story.vjy.me</link>
        <description>Some thoughts, stories and insights</description>
        <language>en</language>
        <lastBuildDate>${new Date().toUTCString()}</lastBuildDate>
  • Defines XML version and encoding
  • Specifies RSS version 2.0
  • Includes atom namespace for enhanced compatibility
  • Sets channel metadata (title, link, description)
  • Uses toUTCString() for standard date format

2. Blog Posts Processing

Object.entries(blogs)
    .sort(([, a], [, b]) => 
        new Date(b.created_at).getTime() - new Date(a.created_at).getTime()
    )
    .map(([id, blog]) => {
        const url = `https://story.vjy.me/${id}`;
        // Generate item XML
    })
  • Converts blog object to array of entries
  • Sorts posts by date (newest first)
  • Maps each blog post to RSS item format

3. Individual Post Items

<item>
    <title><![CDATA[${blog.title}]]></title>
    <link>${url}</link>
    <guid>${id}</guid>
    <description><![CDATA[${blog.description}]]></description>
    <pubDate>${new Date(blog.created_at).toUTCString()}</pubDate>
    <author>${blog.author_id}</author>
    <category>${blog.category}</category>
</item>
  • CDATA sections protect against special characters in title and description
  • guid uses post ID for unique identification
  • pubDate converts blog date to UTC format
  • Includes author and category information

4. Response Headers

return new Response(xml, {
    headers: {
        'Content-Type': 'application/xml; charset=utf-8',
        'Cache-Control': 'public, max-age=3600'
    }
})
  • Sets proper XML content type
  • Enables caching for one hour
  • Returns RSS feed as HTTP response

Usage Example

When a reader visits /feed, they'll receive an RSS feed like this:

<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>realvjy's story</title>
        <link>https://story.vjy.me</link>
        <description>Some thoughts, stories and insights</description>
        <item>
            <title>
            <![CDATA[ Adding RSS Feed to Next.js blog ]]>
            </title>
            <link>https://story.vjy.me/28</link>
            <guid isPermaLink="false">28</guid>
            <description>
                <![CDATA[ How I implemented RSS feed using Next.js App Router's route handlers instead of external packages. ]]>
            </description>
            <pubDate>Fri, 13 Dec 2024 18:30:00 GMT</pubDate>
            <author>realvjy</author>
             <category>Devlog</category>
        </item>
        <!-- More items... -->
    </channel>
</rss>

This implementation provides a standard-compliant RSS feed that works with all major RSS readers while being efficient and maintainable. Check complete code gist here

stay hungry, stay foolish

-Steve Jobs

©realvjyvijay verma