From f728e296e30cfa875c8e9b917de442b8cba35fa7 Mon Sep 17 00:00:00 2001 From: bholmesdev Date: Tue, 8 Oct 2024 11:08:20 -0400 Subject: [PATCH 01/10] docs: improved rss readme --- packages/astro-rss/README.md | 298 +++++++++++++---------------------- 1 file changed, 109 insertions(+), 189 deletions(-) diff --git a/packages/astro-rss/README.md b/packages/astro-rss/README.md index d24c5dabc0d6..aac292afadf0 100644 --- a/packages/astro-rss/README.md +++ b/packages/astro-rss/README.md @@ -2,80 +2,13 @@ This package brings fast RSS feed generation to blogs and other content sites built with [Astro](https://astro.build/). For more information about RSS feeds in general, see [aboutfeeds.com](https://aboutfeeds.com/). -## Installation +## Usage guide -Install the `@astrojs/rss` package into any Astro project using your preferred package manager: - -```bash -# npm -npm i @astrojs/rss -# yarn -yarn add @astrojs/rss -# pnpm -pnpm i @astrojs/rss -``` - -## Example usage - -The `@astrojs/rss` package provides helpers for generating RSS feeds within [Astro endpoints][astro-endpoints]. This unlocks both static builds _and_ on-demand generation when using an [SSR adapter](https://docs.astro.build/en/guides/server-side-rendering/). - -For instance, say you need to generate an RSS feed for all posts under `src/content/blog/` using content collections. - -Start by [adding a `site` to your project's `astro.config` for link generation](https://docs.astro.build/en/reference/configuration-reference/#site). Then, create an `rss.xml.js` file under your project's `src/pages/` directory, and [use `getCollection()`](https://docs.astro.build/en/guides/content-collections/#getcollection) to generate a feed from all documents in the `blog` collection: - -```js -// src/pages/rss.xml.js -import rss from '@astrojs/rss'; -import { getCollection } from 'astro:content'; - -export async function GET(context) { - const posts = await getCollection('blog'); - return rss({ - title: 'Buzz’s Blog', - description: 'A humble Astronaut’s guide to the stars', - // Pull in your project "site" from the endpoint context - // https://docs.astro.build/en/reference/api-reference/#contextsite - site: context.site, - items: posts.map((post) => ({ - // Assumes all RSS feed item properties are in post frontmatter - ...post.data, - // Generate a `url` from each post `slug` - // This assumes all blog posts are rendered as `/blog/[slug]` routes - // https://docs.astro.build/en/guides/content-collections/#generating-pages-from-content-collections - link: `/blog/${post.slug}/`, - })), - }); -} -``` - -Read **[Astro's RSS docs][astro-rss]** for more on using content collections, and instructions for globbing entries in `/src/pages/`. +Read the [`@astrojs/rss` docs][docs] for usage examples. ## `rss()` configuration options -The `rss` default export offers a number of configuration options. Here's a quick reference: - -```js -export function GET(context) { - return rss({ - // `` field in output xml - title: 'Buzz’s Blog', - // `<description>` field in output xml - description: 'A humble Astronaut’s guide to the stars', - // provide a base URL for RSS <item> links - site: context.site, - // list of `<item>`s in output xml - items: [], - // (optional) absolute path to XSL stylesheet in your project - stylesheet: '/rss-styles.xsl', - // (optional) inject custom xml - customData: '<language>en-us</language>', - // (optional) add arbitrary metadata to opening <rss> tag - xmlns: { h: 'http://www.w3.org/TR/html4/' }, - // (optional) add trailing slashes to URLs (default: true) - trailingSlash: false, - }); -} -``` +The `rss()` utility function offers a number of configuration options to generate your feed. ### title @@ -109,81 +42,9 @@ export const GET = (context) => Type: `RSSFeedItem[] (required)` -A list of formatted RSS feed items. See [Astro's RSS items documentation](https://docs.astro.build/en/guides/rss/#generating-items) for usage examples to choose the best option for you. - -When providing a formatted RSS item list, see the [`RSSFeedItem` type reference](#rssfeeditem). - -### stylesheet - -Type: `string (optional)` - -An absolute path to an XSL stylesheet in your project. If you don’t have an RSS stylesheet in mind, we recommend the [Pretty Feed v3 default stylesheet](https://github.com/genmon/aboutfeeds/blob/main/tools/pretty-feed-v3.xsl), which you can download from GitHub and save into your project's `public/` directory. - -### customData - -Type: `string (optional)` - -A string of valid XML to be injected between your feed's `<description>` and `<item>` tags. This is commonly used to set a language for your feed: - -```js -import rss from '@astrojs/rss'; - -export const GET = () => rss({ - ... - customData: '<language>en-us</language>', - }); -``` - -### xmlns - -Type: `Record<string, string> (optional)` - -An object mapping a set of `xmlns` suffixes to strings of metadata on the opening `<rss>` tag. - -For example, this object: - -```js -rss({ - ... - xmlns: { h: 'http://www.w3.org/TR/html4/' }, -}) -``` - -Will inject the following XML: - -```xml -<rss xmlns:h="http://www.w3.org/TR/html4/"... -``` - -### content - -The `content` key contains the full content of the post as HTML. This allows you to make your entire post content available to RSS feed readers. - -**Note:** Whenever you're using HTML content in XML, we suggest using a package like [`sanitize-html`](https://www.npmjs.com/package/sanitize-html) in order to make sure that your content is properly sanitized, escaped, and encoded. - -[See our RSS documentation](https://docs.astro.build/en/guides/rss/#including-full-post-content) for examples using content collections and glob imports. - -### `trailingSlash` - -Type: `boolean (optional)` -Default: `true` - -By default, the library will add trailing slashes to the emitted URLs. To prevent this behavior, add `trailingSlash: false` to the `rss` function. - -```js -import rss from '@astrojs/rss'; +A list of formatted RSS feed items. See [Astro's RSS items documentation][docs] for configuration options and usage examples. -export const GET = () => - rss({ - trailingSlash: false, - }); -``` - -## `RSSFeedItem` - -An `RSSFeedItem` is a single item in the list of items in your feed. It represents a story, with `link`, `title`, and `pubDate` fields. There are further optional fields defined below. You can also check the definitions for the fields in the [RSS spec](https://validator.w3.org/feed/docs/rss2.html#ltpubdategtSubelementOfLtitemgt). - -An example feed item might look like: +An `RSSFeedItem` is a single item in the list of items in your feed. An example feed item might look like: ```js const item = { @@ -196,59 +57,59 @@ const item = { }; ``` -### `title` +#### `title` Type: `string (optional)` The title of the item in the feed. Optional only if a description is set. Otherwise, required. -### `link` +#### `link` Type: `string (optional)` The URL of the item on the web. -### `pubDate` +#### `pubDate` Type: `Date (optional)` Indicates when the item was published. -### `description` +#### `description` Type: `string (optional)` A synopsis of your item when you are publishing the full content of the item in the `content` field. The `description` may alternatively be the full content of the item in the feed if you are not using the `content` field (entity-coded HTML is permitted). Optional only if a title is set. Otherwise, required. -### `content` +#### `content` Type: `string (optional)` -The full text content of the item suitable for presentation as HTML. If used, you should also provide a short article summary in the `description` field. +The full text content of the item suitable for presentation as HTML. If used, you should also provide a short article summary in the `description` field. See the [recommendations from the RSS spec for how to use and differentiate between `description` and `content`](https://www.rssboard.org/rss-profile#namespace-elements-content-encoded). -See the [recommendations from the RSS spec for how to use and differentiate between `description` and `content`](https://www.rssboard.org/rss-profile#namespace-elements-content-encoded). +To render Markdown content from a glob result or from a content collection, see the [content rendering guide](https://docs.astro.build/en/guides/rss/#including-full-post-content). -### `categories` +#### `categories` Type: `string[] (optional)` A list of any tags or categories to categorize your content. They will be output as multiple `<category>` elements. -### `author` +#### `author` Type: `string (optional)` The email address of the item author. This is useful for indicating the author of a post on multi-author blogs. -### `commentsUrl` +#### `commentsUrl` Type: `string (optional)` The URL of a web page that contains comments on the item. -### `source` +#### `source` -Type: `object (optional)` +Type: `{ title: string, url: string } (optional)` An object that defines the `title` and `url` of the original feed for items that have been republished from another source. Both are required properties of `source` for proper attribution. @@ -266,31 +127,15 @@ const item = { }; ``` -#### `source.title` - -Type: `string (required)` - -The name of the original feed in which the item was published. (Note that this is the feed's title, not the individual article title.) - -#### `source.url` - -Type: `string (required)` - -The URL of the original feed in which the item was published. +#### `enclosure` -### `enclosure` - -Type: `object (optional)` +Type: `{ url: string, type: string, length: number } (optional)` An object to specify properties for an included media source (e.g. a podcast) with three required values: `url`, `length`, and `type`. ```js const item = { - title: 'Alpha Centauri: so close you can touch it', - link: '/blog/alpha-centuari', - pubDate: new Date('2023-06-04'), - description: - 'Alpha Centauri is a triple star system, containing Proxima Centauri, the closest star to our sun at only 4.24 light-years away.', + /* ... */ enclosure: { url: '/media/alpha-centauri.aac', length: 124568, @@ -299,25 +144,72 @@ const item = { }; ``` -#### `enclosure.url` +- `enclosure.url` is the URL where the media can be found. If the media is hosted outside of your own domain you must provide a full URL. +- `enclosure.length` is the size of the file found at the `url` in bytes. +- `enclosure.type` is the [MIME type](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types) for the media item found at the `url`. -Type: `string (required)` +### stylesheet -The URL where the media can be found. If the media is hosted outside of your own domain you must provide a full URL. +Type: `string (optional)` -#### `enclosure.length` +An absolute path to an XSL stylesheet in your project. If you don’t have an RSS stylesheet in mind, we recommend the [Pretty Feed v3 default stylesheet](https://github.com/genmon/aboutfeeds/blob/main/tools/pretty-feed-v3.xsl), which you can download from GitHub and save into your project's `public/` directory. -Type: `number (required)` +### customData -The size of the file found at the `url` in bytes. +Type: `string (optional)` -#### `enclosure.type` +A string of valid XML to be injected between your feed's `<description>` and `<item>` tags. This is commonly used to set a language for your feed: -Type: `string (required)` +```js +import rss from '@astrojs/rss'; -The [MIME type](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types) for the media item found at the `url`. +export const GET = () => rss({ + ... + customData: '<language>en-us</language>', + }); +``` -## `rssSchema` +### xmlns + +Type: `Record<string, string> (optional)` + +An object mapping a set of `xmlns` suffixes to strings of metadata on the opening `<rss>` tag. + +For example, this object: + +```js +rss({ + ... + xmlns: { h: 'http://www.w3.org/TR/html4/' }, +}) +``` + +Will inject the following XML: + +```xml +<rss xmlns:h="http://www.w3.org/TR/html4/"... +``` + +### content + + +### `trailingSlash` + +Type: `boolean (optional)` +Default: `true` + +By default, the library will add trailing slashes to the emitted URLs. To prevent this behavior, add `trailingSlash: false` to the `rss` function. + +```js +import rss from '@astrojs/rss'; + +export const GET = () => + rss({ + trailingSlash: false, + }); +``` + +## The `rssSchema` validator When using content collections, you can configure your collection schema to enforce expected [`RSSFeedItem`](#items) properties. Import and apply `rssSchema` to ensure that each collection entry produces a valid RSS feed item: @@ -343,7 +235,7 @@ const blog = defineCollection({ }); ``` -## `pagesGlobToRssItems()` +## The `pagesGlobToRssItems()` function To create an RSS feed from documents in `src/pages/`, use the `pagesGlobToRssItems()` helper. This accepts an `import.meta.glob` result ([see Vite documentation](https://vite.dev/guide/features.html#glob-import)) and outputs an array of valid [`RSSFeedItem`s](#items). @@ -363,7 +255,7 @@ export async function GET(context) { } ``` -## `getRssString()` +## The `getRssString()` function As `rss()` returns a `Response`, you can also use `getRssString()` to get the RSS string directly and use it in your own response: @@ -385,7 +277,35 @@ export async function GET(context) { } ``` -For more on building with Astro, [visit the Astro docs][astro-rss]. +## Support + +- Get help in the [Astro Discord][discord]. Post questions in our `#support` forum, or visit our dedicated `#dev` channel to discuss current development and more! + +- Check our [Astro Integration Documentation][astro-integration] for more on integrations. + +- Submit bug reports and feature requests as [GitHub issues][issues]. + +## Contributing + +This package is maintained by Astro's Core team. You're welcome to submit an issue or PR! These links will help you get started: + +- [Contributor Manual][contributing] +- [Code of Conduct][coc] +- [Community Guide][community] + +## License + +MIT + +Copyright (c) 2023–present [Astro][astro] -[astro-rss]: https://docs.astro.build/en/guides/rss/#using-astrojsrss-recommended +[docs]: https://docs.astro.build/en/guides/rss/ [astro-endpoints]: https://docs.astro.build/en/core-concepts/astro-pages/#non-html-pages +[astro]: https://astro.build/ +[docs]: https://docs.astro.build/en/guides/integrations-guide/alpinejs/ +[contributing]: https://github.com/withastro/astro/blob/main/CONTRIBUTING.md +[coc]: https://github.com/withastro/.github/blob/main/CODE_OF_CONDUCT.md +[community]: https://github.com/withastro/.github/blob/main/COMMUNITY_GUIDE.md +[discord]: https://astro.build/chat/ +[issues]: https://github.com/withastro/astro/issues +[astro-integration]: https://docs.astro.build/en/guides/integrations-guide/ From 9db0658afd21d80b00476075952cbb1f81042553 Mon Sep 17 00:00:00 2001 From: bholmesdev <hey@bholmes.dev> Date: Tue, 8 Oct 2024 11:22:53 -0400 Subject: [PATCH 02/10] chore: changeset --- .changeset/silly-tomatoes-kick.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/silly-tomatoes-kick.md diff --git a/.changeset/silly-tomatoes-kick.md b/.changeset/silly-tomatoes-kick.md new file mode 100644 index 000000000000..f72a57d34005 --- /dev/null +++ b/.changeset/silly-tomatoes-kick.md @@ -0,0 +1,5 @@ +--- +'@astrojs/rss': patch +--- + +Improves README configuration reference. From cb92e892a55a8e69c4f159f473132edbfaab4b63 Mon Sep 17 00:00:00 2001 From: Ben Holmes <hey@bholmes.dev> Date: Tue, 8 Oct 2024 11:33:47 -0400 Subject: [PATCH 03/10] fix: remove empty title Co-authored-by: Armand Philippot <git@armand.philippot.eu> --- packages/astro-rss/README.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/packages/astro-rss/README.md b/packages/astro-rss/README.md index aac292afadf0..7738887261d5 100644 --- a/packages/astro-rss/README.md +++ b/packages/astro-rss/README.md @@ -190,9 +190,6 @@ Will inject the following XML: <rss xmlns:h="http://www.w3.org/TR/html4/"... ``` -### content - - ### `trailingSlash` Type: `boolean (optional)` From 484bae9c8d1ca458288d00fe86b78538b37f4348 Mon Sep 17 00:00:00 2001 From: Ben Holmes <hey@bholmes.dev> Date: Thu, 10 Oct 2024 08:16:38 -0400 Subject: [PATCH 04/10] edit: slash wording Co-authored-by: Sarah Rainsberger <sarah@rainsberger.ca> --- packages/astro-rss/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/astro-rss/README.md b/packages/astro-rss/README.md index 7738887261d5..cf2ec82f51ed 100644 --- a/packages/astro-rss/README.md +++ b/packages/astro-rss/README.md @@ -195,7 +195,7 @@ Will inject the following XML: Type: `boolean (optional)` Default: `true` -By default, the library will add trailing slashes to the emitted URLs. To prevent this behavior, add `trailingSlash: false` to the `rss` function. +By default, trailing slashes will be added to the URLs of your feed entries. To prevent this behavior, add `trailingSlash: false` to the `rss` function. ```js import rss from '@astrojs/rss'; From ccf4ecb411255c31462a4db4f7286b91a46889ca Mon Sep 17 00:00:00 2001 From: Ben Holmes <hey@bholmes.dev> Date: Thu, 10 Oct 2024 08:19:23 -0400 Subject: [PATCH 05/10] edit: installation and use Co-authored-by: Sarah Rainsberger <sarah@rainsberger.ca> --- packages/astro-rss/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/astro-rss/README.md b/packages/astro-rss/README.md index cf2ec82f51ed..d32460749193 100644 --- a/packages/astro-rss/README.md +++ b/packages/astro-rss/README.md @@ -2,7 +2,7 @@ This package brings fast RSS feed generation to blogs and other content sites built with [Astro](https://astro.build/). For more information about RSS feeds in general, see [aboutfeeds.com](https://aboutfeeds.com/). -## Usage guide +## Installation and use Read the [`@astrojs/rss` docs][docs] for usage examples. From 8c98c3f46e57b8984c6b23693c8b7ef6c52b92b7 Mon Sep 17 00:00:00 2001 From: Ben Holmes <hey@bholmes.dev> Date: Thu, 10 Oct 2024 08:19:33 -0400 Subject: [PATCH 06/10] edit: see the guide Co-authored-by: Sarah Rainsberger <sarah@rainsberger.ca> --- packages/astro-rss/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/astro-rss/README.md b/packages/astro-rss/README.md index d32460749193..ebbc802053a6 100644 --- a/packages/astro-rss/README.md +++ b/packages/astro-rss/README.md @@ -4,7 +4,7 @@ This package brings fast RSS feed generation to blogs and other content sites bu ## Installation and use -Read the [`@astrojs/rss` docs][docs] for usage examples. +See the [`@astrojs/rss` guide in the Astro docs][docs] for installation and usage examples. ## `rss()` configuration options From 5758fbb2740693b45b8300746abaa971c8db408e Mon Sep 17 00:00:00 2001 From: Ben Holmes <hey@bholmes.dev> Date: Thu, 10 Oct 2024 08:20:28 -0400 Subject: [PATCH 07/10] edit: remove confusing guide link Co-authored-by: Sarah Rainsberger <sarah@rainsberger.ca> --- packages/astro-rss/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/astro-rss/README.md b/packages/astro-rss/README.md index ebbc802053a6..218d6cea1b1c 100644 --- a/packages/astro-rss/README.md +++ b/packages/astro-rss/README.md @@ -42,7 +42,7 @@ export const GET = (context) => Type: `RSSFeedItem[] (required)` -A list of formatted RSS feed items. See [Astro's RSS items documentation][docs] for configuration options and usage examples. +A list of formatted RSS feed items. An `RSSFeedItem` is a single item in the list of items in your feed. An example feed item might look like: From 2f27993231c35c1796ffd299bddbea62c5661fa5 Mon Sep 17 00:00:00 2001 From: Ben Holmes <hey@bholmes.dev> Date: Thu, 10 Oct 2024 08:23:04 -0400 Subject: [PATCH 08/10] edit: clarify what enclosure is used for Co-authored-by: Sarah Rainsberger <sarah@rainsberger.ca> --- packages/astro-rss/README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/astro-rss/README.md b/packages/astro-rss/README.md index 218d6cea1b1c..811afbdf91f4 100644 --- a/packages/astro-rss/README.md +++ b/packages/astro-rss/README.md @@ -158,7 +158,9 @@ An absolute path to an XSL stylesheet in your project. If you don’t have an RS Type: `string (optional)` -A string of valid XML to be injected between your feed's `<description>` and `<item>` tags. This is commonly used to set a language for your feed: +A string of valid XML to be injected between your feed's `<description>` and `<item>` tags. + +This can be used to pass additional data outside of the standard RSS spec, and is commonly used to set a language for your feed: ```js import rss from '@astrojs/rss'; From 147938d08582f84e0faa2eb05b983e6addf388d8 Mon Sep 17 00:00:00 2001 From: bholmesdev <hey@bholmes.dev> Date: Tue, 15 Oct 2024 11:09:26 -0400 Subject: [PATCH 09/10] edit: remove description vs. content blurb --- packages/astro-rss/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/astro-rss/README.md b/packages/astro-rss/README.md index 811afbdf91f4..57f8e224a387 100644 --- a/packages/astro-rss/README.md +++ b/packages/astro-rss/README.md @@ -85,7 +85,7 @@ A synopsis of your item when you are publishing the full content of the item in Type: `string (optional)` -The full text content of the item suitable for presentation as HTML. If used, you should also provide a short article summary in the `description` field. See the [recommendations from the RSS spec for how to use and differentiate between `description` and `content`](https://www.rssboard.org/rss-profile#namespace-elements-content-encoded). +The full text content of the item suitable for presentation as HTML. If used, you should also provide a short article summary in the `description` field. To render Markdown content from a glob result or from a content collection, see the [content rendering guide](https://docs.astro.build/en/guides/rss/#including-full-post-content). From 46c1bf99fcf2044348ba7ecd5728eb29667edcd6 Mon Sep 17 00:00:00 2001 From: bholmesdev <hey@bholmes.dev> Date: Tue, 15 Oct 2024 11:09:43 -0400 Subject: [PATCH 10/10] new: expand xmlns guide to explain usage --- packages/astro-rss/README.md | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/packages/astro-rss/README.md b/packages/astro-rss/README.md index 57f8e224a387..7eedbb3a0a35 100644 --- a/packages/astro-rss/README.md +++ b/packages/astro-rss/README.md @@ -158,7 +158,7 @@ An absolute path to an XSL stylesheet in your project. If you don’t have an RS Type: `string (optional)` -A string of valid XML to be injected between your feed's `<description>` and `<item>` tags. +A string of valid XML to be injected between your feed's `<description>` and `<item>` tags. This can be used to pass additional data outside of the standard RSS spec, and is commonly used to set a language for your feed: @@ -175,23 +175,28 @@ export const GET = () => rss({ Type: `Record<string, string> (optional)` -An object mapping a set of `xmlns` suffixes to strings of metadata on the opening `<rss>` tag. +An object mapping a set of `xmlns` suffixes to strings values on the opening `<rss>` tag. -For example, this object: +Suffixes expand the available XML tags in your RSS feed, so your content may be read by third-party sources like podcast services or blogging platforms. You'll likely combine `xmlns` with the [`customData`](#customData) attribute to insert custom tags for a given platform. + +This example applies the `itunes` suffix to an RSS feed of podcasts, and uses `customData` to define tags for the author and episode details: ```js rss({ - ... - xmlns: { h: 'http://www.w3.org/TR/html4/' }, + // ... + xmlns: { + itunes: 'http://www.itunes.com/dtds/podcast-1.0.dtd', + }, + customData: '<itunes:author>MF Doom</itunes:author>', + items: episodes.map((episode) => ({ + // ... + customData: `<itunes:episodeType>${episode.frontmatter.type}</itunes:episodeType>` + + `<itunes:duration>${episode.frontmatter.duration}</itunes:duration>` + + `<itunes:explicit>${episode.frontmatter.explicit || false}</itunes:explicit>`, + })), }) ``` -Will inject the following XML: - -```xml -<rss xmlns:h="http://www.w3.org/TR/html4/"... -``` - ### `trailingSlash` Type: `boolean (optional)`