From 3032c18321dfd4f001bc86c094881219bd2e22b7 Mon Sep 17 00:00:00 2001 From: tanishqmanuja Date: Wed, 20 Sep 2023 15:48:31 +0530 Subject: [PATCH] feat: generate og image using templates --- src/utils/generateOgImages.tsx | 54 ++++++-------------- src/utils/og-templates/site.tsx | 87 +++++++++++++++++++++++++++++++++ 2 files changed, 102 insertions(+), 39 deletions(-) create mode 100644 src/utils/og-templates/site.tsx diff --git a/src/utils/generateOgImages.tsx b/src/utils/generateOgImages.tsx index 61b5bc9..c6752b5 100644 --- a/src/utils/generateOgImages.tsx +++ b/src/utils/generateOgImages.tsx @@ -1,8 +1,8 @@ import satori, { type SatoriOptions } from "satori"; -import { writeFile } from "node:fs/promises"; import { Resvg } from "@resvg/resvg-js"; -import { getCollection } from "astro:content"; +import { type CollectionEntry } from "astro:content"; import postOgImage from "./og-templates/post"; +import siteOgImage from "./og-templates/site"; const fetchFonts = async () => { // Regular Font @@ -42,42 +42,18 @@ const options: SatoriOptions = { ], }; -const generateOgImages = async () => { - const postImportResult = await getCollection( - "blog", - ({ data }) => !data.draft - ); - const posts = Object.values(postImportResult).filter( - ({ data }) => !data.ogImage - ); +function svgBufferToPngBuffer(svg: string) { + const resvg = new Resvg(svg); + const pngData = resvg.render(); + return pngData.asPng(); +} - const imageGenerationPromises = posts.map(async post => { - const svg = await satori(postOgImage(post.data.title), options); +export async function generateOgImageForPost(post: CollectionEntry<"blog">) { + const svg = await satori(postOgImage(post), options); + return svgBufferToPngBuffer(svg); +} - // render png in production mode - if (import.meta.env.MODE === "production") { - const resvg = new Resvg(svg); - const pngData = resvg.render(); - const pngBuffer = pngData.asPng(); - - const outputImage = `${post.slug}.png`; - - const LIGHT_BLUE = "\x1b[94m"; - const DARK_GRAY = "\x1b[30m"; - const RESET = "\x1b[0m"; - console.info( - ` ${LIGHT_BLUE}└─${RESET} output png image:`, - `${DARK_GRAY}/${outputImage}${RESET}` - ); - - await writeFile(`./dist/${outputImage}`, pngBuffer); - } - }); - - // Wait for all image generation operations to complete - await Promise.all(imageGenerationPromises); - - return null; -}; - -export default generateOgImages; +export async function generateOgImageForSite() { + const svg = await satori(siteOgImage(), options); + return svgBufferToPngBuffer(svg); +} diff --git a/src/utils/og-templates/site.tsx b/src/utils/og-templates/site.tsx new file mode 100644 index 0000000..33bddc6 --- /dev/null +++ b/src/utils/og-templates/site.tsx @@ -0,0 +1,87 @@ +import { SITE } from "@config"; + +export default () => { + return ( +
+
+ +
+
+
+

{SITE.title}

+

{SITE.desc}

+
+ +
+ + {new URL(SITE.website).hostname} + +
+
+
+
+ ); +};