RSS
Create a basic RSS Feed
- Extend Starlight’s schema (
extend
) withpubDate
andrss
(optional) fields.-
Update
src/content/config.ts
src/content/config.ts import { defineCollection, z } from "astro:content";import { docsSchema } from "@astrojs/starlight/schema";export const collections = {docs: defineCollection({schema: docsSchema({extend: z.object({pubDate: z.date().optional(),rss: z.boolean().optional(),}),}),}),}; -
Update page frontmatter
src/content/docs/**.md title: Titledescription: A description. # recommendedlastUpdated: 2024-11-30sidebar:order: 301label: rsstableOfContents:minHeadingLevel: 2maxHeadingLevel: 2rss: true # optionalpubDate: 2024-11-30 # RSS feed
-
- Install
@astrojs/rss
terminal deno add npm:@astrojs/rss - Create
rss.xml.js
in thesrc/pages/
directory. This file will add RSSitems
through the Starlightdocs
content collection.rss.xml.js import rss from "@astrojs/rss";import { getCollection } from "astro:content";// export function GET(context) {export async function GET(context) {const docs = await getCollection("docs");return rss({// `<title>` field in output xmltitle: "Lucero",// `<description>` field in output xmldescription: "Take your documentation to the moon and back in the blink of an eye.",// Pull in your project "site" from the endpoint context// https://docs.astro.build/en/reference/api-reference/#contextsitesite: `${context.site}/lucero`,// Array of `<item>`s in output xmlitems: docs.map((page) => ({title: page.data.title,pubDate: page.data.pubDate,description: page.data.description,// Compute RSS link from page `slug`link: `/lucero/${page.slug}/`,// content: sanitizeHtml(page.compiledContent()),content: sanitizeHtml.replace(/[\x1B]/g, "&esc;"),})),// (optional) inject custom xmlcustomData: `<language>en-us</language>`,});}
Add an RSS Stylesheet
-
Create a
styles.xsl
file somewhere in thepublic
directory. Or use the recommended the Pretty Feed v3 default Stylesheet.public/rss/styles.xsl <?xml version="1.0" encoding="utf-8"?><!--sourcehttps://github.com/genmon/aboutfeeds/blob/main/tools/pretty-feed-v3.xsl--><xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/"xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd"><xsl:output method="html" version="1.0" encoding="UTF-8" indent="yes"/><xsl:template match="/"><html xmlns="http://www.w3.org/1999/xhtml" lang="en"><head><title><xsl:value-of select="/rss/channel/title" /> Web Feed</title><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" /><linkrel="stylesheet"href="https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.min.css"/></head><body class="bg-white not-content"><main class="container"><header><h2><xsl:value-of select="/rss/channel/title" /></h2><p><xsl:value-of select="/rss/channel/description" /></p><a class="head_link" target="_blank"><xsl:attribute name="href"><xsl:value-of select="/rss/channel/link" /></xsl:attribute>Visit Website →</a><hr/></header><hr/><section><h2><img style="vertical-align: text-bottom; width: 1.2em; height: 1.2em" src="/lucero/rss/rss-icon.svg" class="pr-1" />RSS Feed</h2><hr/><xsl:for-each select="/rss/channel/item"><article><h4><a target="_blank"><xsl:attribute name="href"><xsl:value-of select="link" /></xsl:attribute><xsl:value-of select="title" /></a></h4><p><xsl:value-of select="description" /></p><time><xsl:value-of select="pubDate" /></time></article></xsl:for-each></section></main></body></html></xsl:template></xsl:stylesheet>
Include Content (sanitized)
- Install packages
terminal deno add npm:markdown-it npm:sanitize-html - Update
rss.xml.js
to add thecontent
from eachitem
. This project filters items, checking fordata.rss
, and sorted by descending date.rss.xml.js import rss from "@astrojs/rss";import { getCollection } from "astro:content";// https://github.com/markdown-it/markdown-itimport MarkdownIt from "markdown-it";const markdownParser = new MarkdownIt();// https://github.com/apostrophecms/sanitize-htmlimport sanitizeHtml from "sanitize-html";// export function GET(context) {export async function GET(context) {const docs = await getCollection("docs");const items = docs.filter((page) => page.data.rss === true).sort((a, b) => b.data.pubDate - a.data.pubDate);return rss({// ex. use your stylesheet from "public/rss/styles.xsl"stylesheet: "/lucero/rss/styles.xsl",// `<title>` field in output xmltitle: "Lucero",// `<description>` field in output xmldescription: "Take your documentation to the moon and back in the blink of an eye.",// Pull in your project "site" from the endpoint context// https://docs.astro.build/en/reference/api-reference/#contextsitesite: `${context.site}/lucero`,// Array of `<item>`s in output xml// See "Generating items" section for examples using content collections and glob importsitems: items.map((item) => ({title: item.data.title,pubDate: item.data.pubDate,description: item.data.description,// Compute RSS link from item `slug`link: `/lucero/${item.slug}/`,content: sanitizeHtml(markdownParser.render(item.body),{allowedTags: sanitizeHtml.defaults.allowedTags.concat(["img"]),},).replace(/\x1B/g, "&esc;"),})),// (optional) inject custom xmlcustomData: `<language>en-us</language>`,});}
Enable RSS Auto-discovery
Update the defineConfig.integrations.starlight.head
in the project astro.config.mjs
file with the following
export default defineConfig({ // ... integrations: [ starlight({ title: 'Lucero', head: [ { tag: 'link', attrs: { rel: 'alternate', type: 'application/rss+xml', title: 'Lucero', href: 'https://indyandie.github.io/lucero/rss.xml', }, }, ], // ... }), ],})