跳转到内容

添加 RSS 订阅源

Astro 支持为博客和其他内容网站快速、自动地生成 RSS feed。RSS feed 为用户提供了一种订阅你内容的简单方式。

这个包 @astrojs/rss 提供了使用 API 端点 生成 RSS feed 的辅助函数。这在使用 SSR 适配器 时,可以解锁静态构建按需生成。

  1. 使用你偏好的包管理器安装 @astrojs/rss

    终端窗口
    npm install @astrojs/rss
  2. src/pages/ 目录下创建一个你选择的文件名,并以 .xml.js 为扩展名,作为你的 feed 的输出 URL。一些常见的 RSS feed URL 名称是 feed.xmlrss.xml

    下面的示例文件 src/pages/rss.xml.js 将在 site/rss.xml 创建一个 RSS feed。

  3. @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 xml
    title: 'Buzz’s Blog',
    // `<description>` field in output xml
    description: '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/#site
    site: context.site,
    // Array of `<item>`s in output xml
    // See "Generating items" section for examples using content collections and glob imports
    items: [],
    // (optional) inject custom xml
    customData: `<language>en-us</language>`,
    });
    }
有关完整的配置参考,请参阅 @astrojs/rss 的 README

items 字段接受一个 RSS feed 对象列表,这些对象可以从使用 getCollection() 的内容集合条目中生成,也可以从使用 pagesGlobToRssItems() 的页面文件中生成。

RSS feed 标准格式包含每个已发布项目的元数据,包括以下值:

  • title:条目的标题。仅当设置了 description 时可选。否则为必需。
  • description:条目的简短摘要或描述。仅当设置了 title 时可选。否则为必需。
  • link:指向条目原始来源的 URL。(可选)
  • pubDate:条目的发布日期。(可选)
  • content:你文章的全部内容。(可选)
有关完整的选项列表,请参阅 items 配置参考

要创建在内容集合中管理的页面的 RSS feed,请使用 getCollection() 函数来检索你的 items 数组所需的数据。你需要从返回的数据中为每个所需的属性(例如 titledescription)指定值。

src/pages/rss.xml.js
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 的每个单独属性。

src/content.config.ts
import { defineCollection } from 'astro:content';
import { rssSchema } from '@astrojs/rss';
const blog = defineCollection({
schema: rssSchema,
});
export const collections = { blog };

添加于: @astrojs/rss@2.1.0

要从 src/pages/ 中的文档创建 RSS feed,请使用 pagesGlobToRssItems() 辅助函数。它接受 import.meta.glob 的结果,并输出一个有效的 RSS feed 项目数组(有关指定要包含哪些页面的更多关于编写 glob 模式的信息)。

src/pages/rss.xml.js
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}'),
),
});
}

添加于: astro@1.6.14

content 键包含帖子的完整 HTML 内容。这允许你将整个帖子内容提供给 RSS feed 阅读器。

当使用内容集合时,使用像 markdown-it 这样的标准 Markdown 解析器来渲染帖子的 body,并净化结果,包括渲染内容所需的任何额外标签(例如 <img>

src/pages/rss.xml.js
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 文件。

src/pages/rss.xml.js
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 与你的项目配置相匹配。

src/pages/rss.xml.js
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',
// ...
});

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 阅读器中订阅你的帖子。

贡献 社区 赞助