RSS feed generation library for Astro projects with comprehensive configuration options and TypeScript support
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Core RSS feed generation functionality that creates RSS 2.0 compliant XML feeds with comprehensive configuration options and advanced features.
Main function to generate RSS feed as an HTTP Response suitable for Astro endpoints.
/**
* Generate RSS feed as HTTP Response
* @param options - RSS feed configuration
* @returns Promise<Response> with XML content and application/xml header
*/
function rss(options: RSSOptions): Promise<Response>;Usage Example:
// In src/pages/rss.xml.js
import rss from "@astrojs/rss";
export async function GET(context) {
return rss({
title: "My Blog",
description: "Personal thoughts and tutorials",
site: context.site,
items: [
{
title: "Getting Started with Astro",
link: "/blog/getting-started",
pubDate: new Date("2023-06-01"),
description: "Learn the basics of Astro development",
categories: ["tutorial", "astro"],
author: "john@example.com"
}
],
customData: '<language>en-us</language>',
stylesheet: "/rss-styles.xsl"
});
}Generate RSS feed as XML string for custom response handling or external processing.
/**
* Generate RSS feed as XML string
* @param options - RSS feed configuration
* @returns Promise<string> containing RSS XML
*/
function getRssString(options: RSSOptions): Promise<string>;Usage Example:
import { getRssString } from "@astrojs/rss";
export async function GET(context) {
const rssString = await getRssString({
title: "My Blog",
description: "Personal blog posts",
site: context.site,
items: blogPosts,
});
return new Response(rssString, {
headers: {
"Content-Type": "application/xml",
"Cache-Control": "public, max-age=3600"
},
});
}Comprehensive configuration interface for RSS feed generation.
interface RSSOptions {
/** Title of the RSS Feed (required) */
title: string;
/** Description of the RSS Feed (required) */
description: string;
/**
* Base URL to use for RSS feed links (required)
* Recommend using context.site from Astro endpoint
*/
site: string | URL;
/** List of RSS feed items to render (required) */
items: RSSFeedItem[] | GlobResult;
/** Specify arbitrary XML namespaces on opening <rss> tag */
xmlns?: Record<string, string>;
/**
* Specifies a local custom XSL stylesheet path
* Ex. '/public/custom-feed.xsl' or boolean false to disable
*/
stylesheet?: string | boolean;
/** Specify custom XML data in opening of channel */
customData?: string;
/** Add trailing slashes to URLs (default: true) */
trailingSlash?: boolean;
}Custom XML Namespaces:
// For podcast feeds with iTunes namespace
export const GET = () => rss({
title: "My Podcast",
description: "Weekly tech discussions",
site: "https://example.com",
items: episodes,
xmlns: {
itunes: "http://www.itunes.com/dtds/podcast-1.0.dtd",
googleplay: "http://www.google.com/schemas/play-podcasts/1.0"
},
customData: `
<itunes:author>John Doe</itunes:author>
<itunes:category text="Technology"/>
<googleplay:author>John Doe</googleplay:author>
`,
});Full Content with Media Enclosures:
export const GET = () => rss({
title: "Video Blog",
description: "Weekly video content",
site: "https://example.com",
items: [
{
title: "Episode 1: Introduction",
link: "/episodes/intro",
pubDate: new Date("2023-06-01"),
description: "Welcome to our new series",
content: `
<h1>Episode 1: Introduction</h1>
<p>Full episode transcript and show notes...</p>
<img src="/images/episode1.jpg" alt="Episode thumbnail" />
`,
enclosure: {
url: "/media/episode1.mp4",
length: 52428800, // file size in bytes
type: "video/mp4"
},
categories: ["video", "tutorial"]
}
]
});Custom Stylesheet:
export const GET = () => rss({
title: "Styled Feed",
description: "RSS feed with custom styling",
site: "https://example.com",
items: posts,
stylesheet: "/pretty-feed.xsl", // XSL stylesheet for browser display
});interface RSSFeedItem {
/** Link to item (optional if description provided) */
link?: string;
/** Full HTML content of the item */
content?: string;
/** Title of item (optional if description provided) */
title?: string;
/** Publication date - accepts Date, string, or number */
pubDate?: Date | string | number;
/** Item description (optional if title provided) */
description?: string;
/** Custom XML data to inject into this item */
customData?: string;
/** Categories or tags related to the item */
categories?: string[];
/** The item author's email address */
author?: string;
/** URL of a page for comments related to the item */
commentsUrl?: string;
/** RSS channel that the item came from for republished content */
source?: RSSFeedItemSource;
/** Media object that belongs to the item (podcasts, videos) */
enclosure?: RSSFeedItemEnclosure;
}
interface RSSFeedItemSource {
/** Title of the original RSS channel */
title: string;
/** URL of the original RSS feed */
url: string;
}
interface RSSFeedItemEnclosure {
/** URL where the media can be found */
url: string;
/** Size of the file in bytes */
length: number;
/** MIME type of the media file */
type: string;
}The RSS generation functions provide detailed error messages for validation failures:
Common Validation Errors:
// Missing required fields
// Error: "[RSS] Invalid or missing options:
// At least title or description must be provided. (items)
// The `items` property requires at least the `title` or `description` key..."
// Invalid types
// Error: "[RSS] Invalid or missing options:
// "title" should be string, not undefined. (title)"
// Invalid URL format
// Error: "[RSS] Invalid or missing options:
// "site" should be string, not number. (site)"Error Context: