使用 Astro Container API 输出 RSS 全文

Follow 简单体验,以及使用 Astro Container API 输出 RSS 全文。

昨天 Follow 开始公测,于是便下载体验了一下,界面确实很简洁,功能比我现在用的 Inoreader 更符合我的期望,而且它还可以认证为 RSS 的作者,认证完之后用 Follow 订阅的用户就可以看到作者的认证标识,这个功能很吸引我。但是在我的博客的 RSS 中,只有摘要,没有全文,总觉得少点儿什么,于是便想着怎么把全文输出到 RSS 中。

前段时间看到 Astro 的 Container API,这个 API 可以在服务端获取组件的输出,于是便想到可以用这个 API 来获取全文,然后输出到 RSS 中,今天试了一下还真可以。

Container API

先来看下官方是怎么说的:Container API 允许你在隔离环境中渲染 Astro 组件。不过,这个 API 还在实验阶段,可能会有变化。

用法如下:

import { experimental_AstroContainer } from "astro/container";
const container = await experimental_AstroContainer.create();

RSS 全文输出

大概思路就是在 rss.xml.js 中定义路由,然后在这个路由中使用 Container API 获取全文,最后输出到 RSS 中。

import { loadRenderers } from "astro:container";
import { getCollection } from "astro:content";
import { SITE_DESCRIPTION, SITE_TITLE } from "@/consts";
import { getContainerRenderer } from "@astrojs/mdx";
import rss from "@astrojs/rss";
import { experimental_AstroContainer as AstroContainer } from "astro/container";

export async function GET(context) {
  if (!context.site) {
    throw new TypeError("context.site falsy");
  }

  const container = await AstroContainer.create({
    renderers: await loadRenderers([getContainerRenderer()]),
  });

  const blog = await getCollection("blog");
  const posts = blog
    .filter(({ data: { draft = false } }) => !draft)
    .sort(
      ({ data: { date: dateA } }, { data: { date: dateB } }) =>
        dateB.valueOf() - dateA.valueOf(),
    );

  return rss({
    title: SITE_TITLE,
    description: `${SITE_DESCRIPTION}`,
    site: context.site,
    items: await Promise.all(
      posts.map(async (post) => ({
        ...post.data,
        pubDate: post.data.date,
        description: post.data.tldr,
        link: `/blog/${post.slug}/`,
        content: await container.renderToString((await post.render()).Content),
      })),
    ),
  });
}

Follow 认证

最后,说下怎么添加 Follow 认证。有好几种方式,我这里用的是在 <description> 标签中添加 Follow 生成的 feedId 和 userId。

return rss({
  //...
  description: `${SITE_DESCRIPTION}  feedId:{feedId}+userId:{userId}`,
  // ...
});

评论