Created
September 25, 2024 21:13
-
-
Save NotNite/dedfa28a26f8b3ceb482c230d90ad2c6 to your computer and use it in GitHub Desktop.
Astro Container RSS rendering
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import rss, { type RSSFeedItem } from "@astrojs/rss"; | |
import { getCollection } from "astro:content"; | |
import type { APIContext } from "astro"; | |
import { getContainerRenderer } from "@astrojs/mdx"; | |
import { loadRenderers } from "astro:container"; | |
import { experimental_AstroContainer as AstroContainer } from "astro/container"; | |
import { transform, walk } from "ultrahtml"; | |
import sanitize from "ultrahtml/transformers/sanitize"; | |
import { getBaseURL } from "@/utils"; | |
import RSSRenderer from "@/components/RSSRenderer.astro"; | |
export async function fixLinks(html: string, baseUrl: string) { | |
return await transform(html, [ | |
async (node) => { | |
await walk(node, (node) => { | |
if (node.name === "a" && node.attributes.href?.startsWith("/")) { | |
node.attributes.href = baseUrl + node.attributes.href; | |
} | |
if (node.name === "img" && node.attributes.src?.startsWith("/")) { | |
node.attributes.src = baseUrl + node.attributes.src; | |
} | |
}); | |
return node; | |
}, | |
sanitize({ dropElements: ["script", "style"] }) | |
]); | |
} | |
export async function GET(context: APIContext) { | |
const baseUrl = getBaseURL(context); | |
const blog = await getCollection("blog"); | |
const items: RSSFeedItem[] = []; | |
const renderers = await loadRenderers([getContainerRenderer()]); | |
const container = await AstroContainer.create({ | |
renderers | |
}); | |
for (const post of blog) { | |
let html = await container.renderToString(RSSRenderer, { | |
params: { slug: post.slug } | |
}); | |
html = await fixLinks(html, baseUrl); | |
items.push({ | |
title: post.data.title, | |
description: post.data.description, | |
pubDate: post.data.date, | |
link: baseUrl + `/blog/${post.slug}`, | |
content: html | |
}); | |
} | |
return await rss({ | |
title: "notnite's blog", | |
description: "My ramblings assembled into one tidy place", | |
site: context.site!, | |
items | |
}); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--- | |
import type { ValidContentEntrySlug } from "astro:content"; | |
import { getEntry } from "astro:content"; | |
const { slug } = Astro.params; | |
const entry = await getEntry("blog", slug as ValidContentEntrySlug<"blog">); | |
const { Content } = await entry.render(); | |
--- | |
<Content /> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import type { APIContext } from "astro"; | |
export function getBaseURL(context?: APIContext) { | |
let baseUrl = import.meta.env.PROD | |
? import.meta.env.SITE | |
: (context?.url?.origin ?? "http://localhost:4321"); | |
if (baseUrl.at(-1) === "/") baseUrl = baseUrl.slice(0, -1); | |
return baseUrl; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment