UNPKG

og-images-generator

Version:

Generate OG images from a static folder and / or a middleware. Extract metadata from HTML pages. No headless browser involved. Comes as a CLI, API or plugins.

45 lines (44 loc) 1.99 kB
import satori from 'satori'; import { html as satoriHtml } from 'satori-html'; import { render as renderLit } from '@lit-labs/ssr'; import { collectResultSync } from '@lit-labs/ssr/lib/render-result.js'; import { Resvg } from '@resvg/resvg-js'; import { decodeHTML } from 'entities'; export const fetchFont = async (fontUrl) => fetch(fontUrl).then((response) => response.arrayBuffer()); export const OG_SIZE = { width: 1200, height: 630, }; export const SOURCE_SANS_FONT_URL = 'https://unpkg.com/typeface-source-sans-pro@1.1.13/files/source-sans-pro-400.woff'; export const FONTS = { sourceSans: async () => ({ name: 'Source Sans Pro', data: await fetchFont(SOURCE_SANS_FONT_URL), }), }; export async function renderOgImage(userConfig, page) { const pageOrDefaults = page || { path: '', meta: { tags: {}, jsonLds: [] } }; const templateOptions = { page: pageOrDefaults }; const template = await Promise.resolve(userConfig.template(templateOptions)); /** * `decodeHTML` is a hack because for now, we can't use `unsafeHTML` with * string interpolation (special characters are not encoded by Lit SSR if * they are typed as-is). Also further processors (satori…) are not * decoding the HTML entities. * See this issue: https://github.com/lit/lit/pull/4515 * This is the bug we get with `unsafeHTML` (mixed dev/prod…). * This hack is not optimal and should be removed ASAP. */ const litSsred = decodeHTML(collectResultSync(renderLit(template))); const satoried = satoriHtml(litSsred); const svg = await satori( // @ts-expect-error - FIXME: Mismatch satoried, userConfig.renderOptions.satori); const resvg = new Resvg(svg, userConfig.renderOptions.resvg); const image = resvg.render(); return image.asPng(); } export const renderAllPagesOg = (pages, config) => Promise.all(pages.map(async (page) => ({ path: page.path, data: await renderOgImage(config, page), })));