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
Integration utilities for converting Astro pages and content collections into RSS feed items, enabling seamless content syndication from existing Astro projects.
Helper function to convert Astro pages (from import.meta.glob()) into validated RSS feed items.
/**
* Convert Astro pages glob result to RSS feed items
* @param items - Result from import.meta.glob() of Astro pages
* @returns Promise<RSSFeedItem[]> validated RSS feed items
* @throws Error if pages are outside src/pages/ or missing required frontmatter
*/
function pagesGlobToRssItems(items: GlobResult): Promise<RSSFeedItem[]>;
type GlobResult = Record<string, () => Promise<{
url?: string;
frontmatter: Record<string, any>;
}>>;Usage Example:
// In src/pages/rss.xml.js
import rss, { pagesGlobToRssItems } from "@astrojs/rss";
export async function GET(context) {
return rss({
title: "My Blog",
description: "Latest blog posts",
site: context.site,
// Convert all markdown/mdx files in blog directory to RSS items
items: await pagesGlobToRssItems(
import.meta.glob("./blog/*.{md,mdx}")
),
});
}Pages must have the following frontmatter structure to be converted to RSS items:
interface PageFrontmatter {
/** Page title (required if description not provided) */
title?: string;
/** Page description (required if title not provided) */
description?: string;
/** Publication date - accepts Date, string, or number */
pubDate?: Date | string | number;
/** Custom XML data for this item */
customData?: string;
/** Categories or tags */
categories?: string[];
/** Author email address */
author?: string;
/** Comments URL */
commentsUrl?: string;
/** Original source information */
source?: {
title: string;
url: string;
};
/** Media enclosure */
enclosure?: {
url: string;
length: number;
type: string;
};
}Example Page Frontmatter:
---
title: "Getting Started with Astro"
description: "Learn the fundamentals of building websites with Astro"
pubDate: 2023-06-01
categories: ["tutorial", "astro", "web-development"]
author: "developer@example.com"
---
# Getting Started with Astro
Page content here...Blog with Categories:
// src/pages/rss.xml.js
import rss, { pagesGlobToRssItems } from "@astrojs/rss";
export async function GET(context) {
const blogItems = await pagesGlobToRssItems(
import.meta.glob("./blog/**/*.{md,mdx}")
);
return rss({
title: "Tech Blog",
description: "Latest articles on web development",
site: context.site,
items: blogItems,
customData: "<language>en-us</language>",
});
}Podcast Feed with Media:
// src/pages/podcast.xml.js
import rss, { pagesGlobToRssItems } from "@astrojs/rss";
export async function GET(context) {
const episodes = await pagesGlobToRssItems(
import.meta.glob("./episodes/*.{md,mdx}")
);
return rss({
title: "My Podcast",
description: "Weekly tech discussions",
site: context.site,
items: episodes,
xmlns: {
itunes: "http://www.itunes.com/dtds/podcast-1.0.dtd"
},
customData: `
<itunes:author>John Doe</itunes:author>
<itunes:category text="Technology"/>
<itunes:explicit>false</itunes:explicit>
`,
});
}For non-page content or custom data sources, manually construct RSS items:
// src/pages/rss.xml.js
import rss from "@astrojs/rss";
import { getCollection } from "astro:content";
export async function GET(context) {
// Get content from Astro content collections
const blogPosts = await getCollection("blog");
const rssItems = blogPosts.map(post => ({
title: post.data.title,
description: post.data.description,
link: `/blog/${post.slug}`,
pubDate: post.data.publishDate,
categories: post.data.tags,
author: post.data.author,
}));
return rss({
title: "My Blog",
description: "Latest posts",
site: context.site,
items: rssItems,
});
}The pagesGlobToRssItems() function validates each page and provides detailed error messages:
// Example error scenarios:
// 1. Pages outside src/pages/
// Error: "[RSS] You can only glob entries within 'src/pages/' when passing import.meta.glob() directly."
// 2. Missing required frontmatter
// Error: "[RSS] /src/pages/blog/post.md has invalid or missing frontmatter.
// Fix the following properties:
// At least title or description must be provided."
// 3. Invalid frontmatter types
// Error: "[RSS] /src/pages/blog/post.md has invalid or missing frontmatter.
// Fix the following properties:
// "pubDate" should be string, not number."Note: Passing glob results directly to the items property is deprecated:
// ❌ Deprecated (still works but shows warning)
export const GET = () => rss({
title: "My Blog",
description: "Latest posts",
site: "https://example.com",
items: import.meta.glob("./blog/*.{md,mdx}"), // Shows deprecation warning
});
// ✅ Recommended
export const GET = async () => rss({
title: "My Blog",
description: "Latest posts",
site: "https://example.com",
items: await pagesGlobToRssItems(import.meta.glob("./blog/*.{md,mdx}")),
});