Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/ddamato/astro-mdx-rss

Implementation to render Astro MDX into RSS feed
https://github.com/ddamato/astro-mdx-rss

astro mdx rss

Last synced: 4 days ago
JSON representation

Implementation to render Astro MDX into RSS feed

Awesome Lists containing this project

README

        

# Astro MDX RSS Starter

> [!WARNING]
> This doesn't work as a built site, but it does work in local dev. I have an [open proposal](https://github.com/withastro/roadmap/discussions/881) to help this concept along and potentially omit the need for `rss.xml.js` as a proxy for the resulting XML.

Check out the example by visiting [https://ddamato.github.io/astro-mdx-rss/rss.xml](https://ddamato.github.io/astro-mdx-rss/rss.xml)

Did you expect to render MDX posts into your RSS feed with Astro, only to find out that you can only render MDX in `.astro` files? Yep, me too.

Astro is working on the [Container API](https://github.com/withastro/roadmap/issues/533) which is expected to solve the problem. In the meantime, you can consider this repo which uses Astro's blog starter as the base with a few updates.

- Add `mdx` integration.
- All content files are `.mdx`.
- Added `/pages/rss.astro`.

## `pages/rss.xml.js`

Instead of using `@astrojs/rss` to create the RSS feed, we're going to take the response from the new `/pages/rss.astro` file and send it out with a new header.

```js
export async function GET(context) {
const endpoint = new URL('/rss', context.url.origin);
const xml = await fetch(endpoint).then((res) => res.text());
return new Response(xml, {
status: 200,
headers: new Headers({ 'Content-type': 'text/xml;charset=UTF-8' })
});
}
```

- The `/rss` route points to the `/rss` page (more specifically, `/pages/rss.astro`).
- We get the response text from that request, and set it as the body of the upcoming response.
- We add the `'Content-type: text/xml;charset=UTF-8'` header to let the browser know this is XML.

## `/pages/rss.astro`

This page builds the RSS feed and it has a few gotchas.

```.astro
---
export const partial = true;
import { getCollection } from 'astro:content';
import { SITE_TITLE, SITE_DESCRIPTION } from '../consts';
const posts = await getCollection('blog');
---


{ SITE_TITLE }
{ SITE_DESCRIPTION }
${ Astro.url.origin }` }/>

{ posts.map(async (post) => {
const url = new URL(`blog/${post.slug}`, Astro.url.origin).toString();
const { Content } = await post.render();
return (

{post.data.title}
${ url }` }/>
{ url }
{ post.data.description }
{ post.data.pubDate }




]]>


)
}) }

```

- The `export const partial = true;` tells Astro to _not_ add the expected ``, ``, and `` tags and to treat this as an [HTML partial](https://docs.astro.build/en/basics/astro-pages/#page-partials).
- The `${ Astro.url.origin }` }/>` is needed because Astro considers `` to be a self-closing tag and won't render the ending tag causing the feed to be invalid. We circumvent this by writing the HTML using `set:html` in a ``.
- The whole purpose of this is the `` element, which _must_ be rendered in an `.astro` file. We flank both sides with `` elements which tells Astro not to process anything between the `` tags. This allows the `` and `CDATA` to render as a string.

> [!NOTE]
> Hitting `/rss` in the browser does not provide an XML response, but an HTML one. So mileage may vary about how valid that appears to syndication.

And now hitting `/rss.xml` should provide a fully qualified RSS feed with rendered MDX! You'll most likely need to update the `/pages/rss.astro` file for a more detailed feed.