|
1 | | -import rss from '@astrojs/rss'; |
2 | | -import { getCollection } from 'astro:content'; |
| 1 | +import rss, { pagesGlobToRssItems } from '@astrojs/rss'; |
3 | 2 | import { SITE_TITLE, SITE_DESCRIPTION } from '../consts'; |
4 | 3 |
|
5 | 4 | export async function GET(context) { |
6 | | - // Fetch all blog posts; filter out drafts (assuming you use a `draft` flag in frontmatter) |
7 | | - const posts = await getCollection('blog', ({ data }) => !data.draft); |
| 5 | + // Get the raw site URL from context (ensure it's a string) and remove any trailing slash. |
| 6 | + const rawSite = typeof context.site === 'string' ? context.site : context.site.href; |
| 7 | + const trimmedSite = rawSite.replace(/\/$/, ''); |
| 8 | + |
| 9 | + // Our configured base path from astro.config.mjs |
| 10 | + const basePath = '/cookbook/'; |
| 11 | + // Construct the full site URL (e.g., "https://nicholasdbrady.github.io/cookbook/") |
| 12 | + const fullSiteUrl = trimmedSite + basePath; |
8 | 13 |
|
9 | | - // Get the absolute site URL from the context (configured in astro.config.mjs) |
10 | | - const siteUrl = context.site; |
11 | | - const basePath = '/cookbook/'; // Your configured base |
| 14 | + // Use pagesGlobToRssItems() to automatically generate RSS items from your blog pages. |
| 15 | + // This assumes your published blog pages live in src/pages/blog/. |
| 16 | + let items = await pagesGlobToRssItems(import.meta.glob('./blog/*.{astro,md,mdx}')); |
12 | 17 |
|
13 | | - // Process each post to create an RSS feed item. |
14 | | - const items = await Promise.all(posts.map(async (post) => { |
15 | | - // Render the post (if necessary) to get the HTML. |
16 | | - // If your loader already produces HTML in post.body, you can skip this. |
17 | | - const { Content } = await post.render(); |
| 18 | + // Filter out the dynamic route file (i.e. [...slug].astro) which doesn't have its own frontmatter. |
| 19 | + items = items.filter(item => !item.file.includes('[...slug]')); |
18 | 20 |
|
19 | | - // If your frontmatter includes a heroImage (a relative path), convert it to an absolute URL |
20 | | - const heroImageHTML = post.data.heroImage |
21 | | - ? `<p><img src="${new URL(post.data.heroImage, siteUrl).href}" alt="${post.data.title} Hero Image" /></p>` |
22 | | - : ''; |
| 21 | + // Post-process each item so that its link and guid are built from the fullSiteUrl. |
| 22 | + items = items.map(item => { |
| 23 | + // Remove any leading slash from the item.link (if present) |
| 24 | + const relativePath = item.link.startsWith('/') ? item.link.substring(1) : item.link; |
| 25 | + // Build the final URL using fullSiteUrl as the base. |
| 26 | + const fixedLink = new URL(relativePath, fullSiteUrl).href; |
| 27 | + return { |
| 28 | + ...item, |
| 29 | + link: fixedLink, |
| 30 | + guid: fixedLink, |
| 31 | + }; |
| 32 | + }); |
23 | 33 |
|
24 | | - return { |
25 | | - title: post.data.title, |
26 | | - // Construct the link using your collection's URL structure |
27 | | - link: new URL(`blog/${post.slug}/`, siteUrl + basePath).href, |
28 | | - pubDate: post.data.pubDate, |
29 | | - // Use a short summary as description; if you want to include the full content, set it in content |
30 | | - description: post.data.description, |
31 | | - // Prepend the hero image (if available) to the post body |
32 | | - content: heroImageHTML + post.body, |
33 | | - // Include categories if available (from your frontmatter, e.g., tags) |
34 | | - categories: post.data.tags || [], |
35 | | - // (Optional) Add an author field if you want |
36 | | - author: post.data.author || undefined, |
37 | | - }; |
38 | | - })); |
39 | | - |
40 | | - return rss({ |
41 | | - title: SITE_TITLE, // Your feed title |
42 | | - description: SITE_DESCRIPTION, // A short description of your feed |
43 | | - site: siteUrl, // The absolute base URL of your site |
44 | | - items, // The array of RSS feed items you just created |
45 | | - trailingSlash: false, |
46 | | - }); |
| 34 | + return rss({ |
| 35 | + title: SITE_TITLE, // Your feed title |
| 36 | + description: SITE_DESCRIPTION, // Your feed description |
| 37 | + site: fullSiteUrl, // Ensures the channel <link> includes the base path |
| 38 | + items, // The list of RSS items with full HTML content |
| 39 | + trailingSlash: true, |
| 40 | + customData: `<language>en-us</language>`, // Optional extra XML data |
| 41 | + }); |
47 | 42 | } |
48 | | - |
0 commit comments