Skip to content

Instantly share code, notes, and snippets.

@freekrai
Created November 21, 2022 23:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save freekrai/349b17944aba69f74576ba181a393261 to your computer and use it in GitHub Desktop.
Save freekrai/349b17944aba69f74576ba181a393261 to your computer and use it in GitHub Desktop.
Remix og-images
export const generateSvg = async ({
title='',
subtitle='',
}) => {
const res = await fetch('https://codedgeekery.com/fonts/hack/woff/hack-regular.woff');
const font = await res.arrayBuffer();
const {default: satori} = await import('satori');
return satori(
<div
style={{
fontSize: 128,
fontFamily: 'Hack',
background: 'white',
width: '100%',
height: '100%',
display: 'flex',
textAlign: 'center',
alignItems: 'center',
justifyContent: 'center',
}}
>
{title}
</div>,
{
width: 1200,
height: 600,
embedFont: false,
fonts: [
{
name: 'Hack',
data: font,
weight: 400,
style: 'normal',
}
],
},
)
}
import type { MetaFunction, LoaderArgs, HeadersFunction } from "@remix-run/node";
import { renderAsync } from '@resvg/resvg-js'
import { generateSvg } from '~/utils/og.server'
import {getPostById} from '~/services/directus.server';
export let headers: HeadersFunction = () => {
return { "Cache-Control": new CacheControl("swr").toString() };
};
export async function loader ({ request }: LoaderArgs) {
const url = new URL(request.url);
let pid = url.searchParams.get("p") ?? null;
let type = url.searchParams.get("type") || "svg";
if( pid ) {
const post = await getPostById(pid);
title = post.title;
subtitle = post.slug;
}
const svg = await generateSvg({
title: decodeURIComponent(title),
subtitle: `https://codedgeekery.com/blog/${decodeURIComponent(subtitle)}`
})
if (type === 'svg') {
return new Response(svg, {
headers: {
"Content-Type": "image/svg+xml",
"Cache-Control": new CacheControl("swr").toString(),
},
});
}
// otherwise, generate a png file
const data = await renderAsync(svg, {
fitTo: {
mode: 'width',
value: 1200,
},
font: {
loadSystemFonts: false,
},
})
return new Response(data.asPng(), {
headers: {
"Content-Type": "image/png",
},
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment