添加 RSS 订阅源
Astro 支持为博客和其他内容网站快速、自动地生成 RSS feed。RSS feed 为用户提供了一种订阅你内容的简单方式。
设置 @astrojs/rss
标题为“设置 @astrojs/rss”的部分这个包 @astrojs/rss
提供了使用 API 端点 生成 RSS feed 的辅助函数。这在使用 SSR 适配器 时,可以解锁静态构建和按需生成。
-
使用你偏好的包管理器安装
@astrojs/rss
终端窗口 npm install @astrojs/rss终端窗口 pnpm add @astrojs/rss终端窗口 yarn add @astrojs/rss请确保你已经在项目的
astro.config
文件中配置了site
。它将被用来为你的 RSS 文章生成链接。 -
在
src/pages/
目录下创建一个你选择的文件名,并以.xml.js
为扩展名,作为你的 feed 的输出 URL。一些常见的 RSS feed URL 名称是feed.xml
或rss.xml
。下面的示例文件
src/pages/rss.xml.js
将在site/rss.xml
创建一个 RSS feed。 -
从
@astrojs/rss
包中导入rss()
辅助函数到你的.xml.js
文件中,并导出一个函数,该函数使用以下参数返回它src/pages/rss.xml.js import rss from '@astrojs/rss';export function GET(context) {return rss({// `<title>` field in output xmltitle: 'Buzz’s Blog',// `<description>` field in output xmldescription: 'A humble Astronaut’s guide to the stars',// Pull in your project "site" from the endpoint context// https://docs.astro.js.cn/en/reference/api-reference/#sitesite: context.site,// Array of `<item>`s in output xml// See "Generating items" section for examples using content collections and glob importsitems: [],// (optional) inject custom xmlcustomData: `<language>en-us</language>`,});}
@astrojs/rss
的 README。
生成 items
标题为“生成 `items`”的部分items
字段接受一个 RSS feed 对象列表,这些对象可以从使用 getCollection()
的内容集合条目中生成,也可以从使用 pagesGlobToRssItems()
的页面文件中生成。
RSS feed 标准格式包含每个已发布项目的元数据,包括以下值:
title
:条目的标题。仅当设置了description
时可选。否则为必需。description
:条目的简短摘要或描述。仅当设置了title
时可选。否则为必需。link
:指向条目原始来源的 URL。(可选)pubDate
:条目的发布日期。(可选)content
:你文章的全部内容。(可选)
items
配置参考。
使用内容集合
标题为“使用内容集合”的部分要创建在内容集合中管理的页面的 RSS feed,请使用 getCollection()
函数来检索你的 items
数组所需的数据。你需要从返回的数据中为每个所需的属性(例如 title
、description
)指定值。
import rss from '@astrojs/rss';import { getCollection } from 'astro:content';
export async function GET(context) { const blog = await getCollection('blog'); return rss({ title: 'Buzz’s Blog', description: 'A humble Astronaut’s guide to the stars', site: context.site, items: blog.map((post) => ({ title: post.data.title, pubDate: post.data.pubDate, description: post.data.description, // Compute RSS link from post `id` // This example assumes all posts are rendered as `/blog/[id]` routes link: `/blog/${post.id}/`, })), });}
可选:替换你现有的博客集合 schema 以强制执行预期的 RSS 属性。
为确保每个博客条目都生成有效的 RSS feed 项目,你可以选择导入并应用 rssSchema
,而不是定义你的 schema 的每个单独属性。
import { defineCollection } from 'astro:content';import { rssSchema } from '@astrojs/rss';
const blog = defineCollection({ schema: rssSchema,});
export const collections = { blog };
使用 glob 导入
标题为“使用 glob 导入”的部分
添加于: @astrojs/rss@2.1.0
要从 src/pages/
中的文档创建 RSS feed,请使用 pagesGlobToRssItems()
辅助函数。它接受 import.meta.glob
的结果,并输出一个有效的 RSS feed 项目数组(有关指定要包含哪些页面的更多关于编写 glob 模式的信息)。
此函数假定(但不验证)每个文档的 frontmatter 中都存在所有必需的 feed 属性。如果遇到错误,请手动验证每个页面的 frontmatter。
import rss, { pagesGlobToRssItems } from '@astrojs/rss';
export async function GET(context) { return rss({ title: 'Buzz’s Blog', description: 'A humble Astronaut’s guide to the stars', site: context.site, items: await pagesGlobToRssItems( import.meta.glob('./blog/*.{md,mdx}'), ), });}
在 v2.1.0 之前的 @astrojs/rss
版本中,将你的 glob 结果直接传递给 items
,而无需 pagesGlobToRssItems()
包装器
items: import.meta.glob('./blog/*.{md,mdx}'),
自 Astro v2.1.0 起,此方法已对所有 Astro 版本弃用,并且不能在现代项目中使用。
包含完整的帖子内容
标题为“包含完整的帖子内容”的部分
添加于: astro@1.6.14
content
键包含帖子的完整 HTML 内容。这允许你将整个帖子内容提供给 RSS feed 阅读器。
像 sanitize-html
这样的包将确保你的内容被正确地净化、转义和编码。在此过程中,这样的包也可能移除一些无害的元素和属性,所以请务必验证输出并根据你的需要配置该包。
当使用内容集合时,使用像 markdown-it
这样的标准 Markdown 解析器来渲染帖子的 body
,并净化结果,包括渲染内容所需的任何额外标签(例如 <img>
)
import rss from '@astrojs/rss';import { getCollection } from 'astro:content';import sanitizeHtml from 'sanitize-html';import MarkdownIt from 'markdown-it';const parser = new MarkdownIt();
export async function GET(context) { const blog = await getCollection('blog'); return rss({ title: 'Buzz’s Blog', description: 'A humble Astronaut’s guide to the stars', site: context.site, items: blog.map((post) => ({ link: `/blog/${post.id}/`, // Note: this will not process components or JSX expressions in MDX files. content: sanitizeHtml(parser.render(post.body), { allowedTags: sanitizeHtml.defaults.allowedTags.concat(['img']) }), ...post.data, })), });}
当使用 glob 导入 Markdown 时,你可以使用 compiledContent()
辅助函数来检索渲染后的 HTML 以进行净化。注意:此功能 不 支持 MDX 文件。
import rss from '@astrojs/rss';import sanitizeHtml from 'sanitize-html';
export async function GET(context) { const postImportResult = import.meta.glob('../posts/**/*.md', { eager: true }); const posts = Object.values(postImportResult); return rss({ title: 'Buzz’s Blog', description: 'A humble Astronaut’s guide to the stars', site: context.site, items: await Promise.all(posts.map(async (post) => ({ link: post.url, content: sanitizeHtml((await post.compiledContent())), ...post.frontmatter, }))), });}
移除末尾斜杠
标题为“移除末尾斜杠”的部分默认情况下,Astro 的 RSS feed 生成的链接带有末尾斜杠,无论你为 trailingSlash
配置了什么值。这意味着你的 RSS 链接可能与你的帖子 URL 不完全匹配。
如果你在 astro.config.mjs
中设置了 trailingSlash: "never"
,请在 rss()
辅助函数中设置 trailingSlash: false
,以便你的 feed 与你的项目配置相匹配。
import rss from '@astrojs/rss';
export function GET(context) { const posts = Object.values(postImportResult); return rss({ title: 'Buzz’s Blog', description: 'A humble Astronaut’s guide to the stars', site: context.site, trailingSlash: false, items: posts.map((post) => ({ link: post.url, ...post.frontmatter, })), });}
添加样式表
标题为“添加样式表”的部分为你的 RSS feed 设置样式,以便在浏览器中查看文件时获得更愉悦的用户体验。
使用 rss
函数的 stylesheet
选项来指定样式表的绝对路径。
rss({ // ex. use your stylesheet from "public/rss/styles.xsl" stylesheet: '/rss/styles.xsl', // ...});
如果你不想创建自己的样式表,可以使用预制的样式表,例如 Pretty Feed v3 默认样式表。从 GitHub 下载该样式表并将其保存到项目的 public/
目录中。
启用 RSS feed 自动发现
标题为“启用 RSS feed 自动发现”的部分RSS 自动发现允许浏览器和其他软件从主 URL 自动找到网站的 RSS feed。
要启用,请将具有以下属性的 <link>
标签添加到你网站的 head
元素中
<link rel="alternate" type="application/rss+xml" title="Your Site's Title" href={new URL("rss.xml", Astro.site)}/>
有了这个标签,你的博客读者可以在他们的 RSS 阅读器中输入你网站的基本 URL 来订阅你的帖子,而无需知道你 RSS feed 的具体 URL。
后续步骤
标题为“后续步骤”的部分在浏览器中访问 your-domain.com/rss.xml
并确认你可以看到每个帖子的数据后,你现在可以在你的网站上推广你的 feed。在你的网站上添加标准的 RSS 图标,让你的读者知道他们可以在自己的 feed 阅读器中订阅你的帖子。